Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.60 KB | None | 0 0
  1. import React, { useState, useEffect, FunctionComponent } from "react"
  2. import { View, ViewStyle, TextStyle, RefreshControl } from "react-native"
  3. import { FlatList } from "react-navigation"
  4. import { NavigationStackScreenProps } from "react-navigation-stack"
  5.  
  6. import { Observer, inject } from "mobx-react"
  7. import { Placeholder, PlaceholderMedia, Shine, PlaceholderLine, Fade } from "rn-placeholder"
  8. import { Card } from "../../components/card"
  9. import { Screen } from "../../components/screen"
  10. import { color, spacing, typography } from "../../theme"
  11. import { Tag } from "../../components/tag"
  12. import { NavigatorScreenProps, NavigationStore } from "../../navigation/navigation-store"
  13. import { Header } from "../../components/header"
  14. import { SpaceStore, AppendSpaceSnapshot } from "../../models/space-store"
  15.  
  16. const noop = () => null
  17.  
  18. interface SpaceListScreenProps
  19. extends NavigationStackScreenProps<{
  20. screenSprops: NavigatorScreenProps
  21. }> {
  22. spaceStore: SpaceStore
  23. navigationStore: NavigationStore
  24. }
  25.  
  26. interface SpaceListSpaceState {
  27. isRefreshing: boolean
  28. }
  29.  
  30. const LIST_CONTAINER: ViewStyle = {
  31. alignItems: "center",
  32. paddingBottom: spacing[5],
  33. }
  34.  
  35. const LIST: ViewStyle = {
  36. paddingHorizontal: spacing[5],
  37. }
  38.  
  39. const HEADER: ViewStyle = {
  40. backgroundColor: color.palette.grayFAF,
  41. paddingBottom: 0,
  42. marginBottom: 0,
  43. }
  44.  
  45. const HEADER_LEFT_TEXT: TextStyle = {
  46. color: color.palette.black,
  47. fontSize: 20,
  48. fontFamily: typography.headerBold,
  49. }
  50.  
  51. const HEADER_RIGHT_TEXT: TextStyle = {
  52. color: color.primaryDarker,
  53. fontFamily: typography.primaryBold,
  54. marginTop: 4,
  55. }
  56.  
  57. const SPACE_LIST_TAGS: ViewStyle = {
  58. flexDirection: "row",
  59. justifyContent: "flex-start",
  60. flexGrow: 0,
  61. flexShrink: 0,
  62. flexWrap: "wrap",
  63. }
  64.  
  65. const TAG: ViewStyle = {
  66. flexDirection: "row",
  67. flexWrap: "nowrap",
  68. alignItems: "center",
  69. backgroundColor: color.palette.white,
  70. }
  71.  
  72. const TAG_PREFIX: TextStyle = {
  73. color: color.palette.gray949,
  74. fontFamily: typography.primaryBold,
  75. fontSize: 12,
  76. lineHeight: 12,
  77. marginRight: spacing[1],
  78. }
  79.  
  80. const TAG_VALUE: TextStyle = {
  81. color: color.palette.gray5F6,
  82. fontFamily: typography.primaryBold,
  83. lineHeight: 12,
  84. }
  85.  
  86. const PLACEHOLDER_TAG: ViewStyle = {
  87. borderRadius: 1,
  88. marginRight: spacing[2],
  89. marginBottom: spacing[2],
  90. }
  91.  
  92. const PLACEHOLDER_CARD_WRAPPER: ViewStyle = {
  93. width: "100%",
  94. shadowColor: "#000",
  95. shadowOffset: {
  96. width: 0,
  97. height: 1,
  98. },
  99. shadowOpacity: 0.12,
  100. shadowRadius: 2.22,
  101. elevation: 1,
  102. }
  103.  
  104. const PLACEHOLDER_CARD: ViewStyle = {
  105. height: 288,
  106. marginTop: 16,
  107. borderRadius: 3,
  108. width: "100%",
  109. backgroundColor: color.palette.offWhite,
  110. }
  111.  
  112. interface SpaceListSpace extends AppendSpaceSnapshot {
  113. averageRating: number
  114. }
  115.  
  116. const SpaceList: FunctionComponent<SpaceListScreenProps> = props => {
  117. const [isRefreshing, setIsRefreshing] = useState(false)
  118.  
  119. const { spaces, apiFindOneSpace, apiFindManySpace, resetSpaces } = props.spaceStore
  120. const { navigateTo, showSpinnerModal, hideSpinnerModal } = props.navigationStore
  121. const data = isRefreshing ? [{ id: 1 }, { id: 2 }, { id: 3 }] : spaces
  122.  
  123. const onCardPress = async (id: string) => {
  124. showSpinnerModal()
  125. await apiFindOneSpace({
  126. id,
  127. })
  128. navigateTo("space")
  129. hideSpinnerModal()
  130. }
  131.  
  132. const renderCard = ({ item }) => {
  133. const space: SpaceListSpace = item
  134.  
  135. if (isRefreshing) {
  136. return (
  137. <View style={PLACEHOLDER_CARD_WRAPPER}>
  138. <Placeholder Animation={Fade}>
  139. <PlaceholderMedia style={PLACEHOLDER_CARD} />
  140. </Placeholder>
  141. </View>
  142. )
  143. }
  144.  
  145. return (
  146. <Card
  147. titleText={space.title}
  148. onPress={() => onCardPress(space.id)}
  149. subTitleText={space.spaceLocationFormatted}
  150. tagText="/hr"
  151. tagPrefixText={`$${space.price.hourly}`}
  152. rating={space.averageRating}
  153. imageURL={space.images[0].url}
  154. />
  155. )
  156. }
  157.  
  158. const refreshSpaces = async () => {
  159. setIsRefreshing(true)
  160. resetSpaces()
  161. await apiFindManySpace()
  162. setIsRefreshing(false)
  163. }
  164.  
  165. const renderTags = () => {
  166. if (isRefreshing) {
  167. return (
  168. <Placeholder Animation={Shine}>
  169. <View style={SPACE_LIST_TAGS}>
  170. <PlaceholderLine height={15} width={21} style={PLACEHOLDER_TAG} />
  171. <PlaceholderLine width={25} style={PLACEHOLDER_TAG} />
  172. <PlaceholderLine width={43} style={PLACEHOLDER_TAG} />
  173. <PlaceholderLine width={30} style={PLACEHOLDER_TAG} />
  174. </View>
  175. </Placeholder>
  176. )
  177. }
  178. return (
  179. <View style={SPACE_LIST_TAGS}>
  180. <Tag
  181. style={TAG}
  182. prefixTx={null}
  183. tx="spaceListScreen.tags.time.value"
  184. prefixTextStyle={TAG_PREFIX}
  185. textStyle={TAG_VALUE}
  186. />
  187. <Tag
  188. style={TAG}
  189. prefixTx="spaceListScreen.tags.location.prefix"
  190. tx="spaceListScreen.tags.location.value"
  191. prefixTextStyle={TAG_PREFIX}
  192. textStyle={TAG_VALUE}
  193. />
  194. <Tag
  195. style={TAG}
  196. prefixTx="spaceListScreen.tags.activity.prefix"
  197. tx="spaceListScreen.tags.activity.value"
  198. prefixTextStyle={TAG_PREFIX}
  199. textStyle={TAG_VALUE}
  200. />
  201. <Tag
  202. style={TAG}
  203. prefixTx="spaceListScreen.tags.amenities.prefix"
  204. tx="spaceListScreen.tags.amenities.value"
  205. prefixTextStyle={TAG_PREFIX}
  206. textStyle={TAG_VALUE}
  207. />
  208. </View>
  209. )
  210. }
  211.  
  212. useEffect(() => {
  213. refreshSpaces()
  214. }, [])
  215.  
  216. return (
  217. <Observer>
  218. {() => (
  219. <Screen
  220. preset="scroll"
  221. backgroundColor={color.palette.grayFAF}
  222. refreshControl={
  223. <RefreshControl
  224. onRefresh={refreshSpaces}
  225. refreshing={isRefreshing}
  226. tintColor={color.primary}
  227. colors={[color.primary, color.primaryDarker]}
  228. style={{ backgroundColor: "transparent" }}
  229. />
  230. }>
  231. <FlatList
  232. style={LIST}
  233. contentContainerStyle={LIST_CONTAINER}
  234. data={data}
  235. keyExtractor={item => String(item.id)}
  236. renderItem={renderCard}
  237. ListHeaderComponent={renderTags()}
  238. />
  239. </Screen>
  240. )}
  241. </Observer>
  242. )
  243. }
  244.  
  245. export const SpaceListScreen = inject("spaceStore", "navigationStore")(SpaceList)
  246.  
  247. SpaceListScreen.navigationOptions = ({ navigation }) => ({
  248. header: (
  249. <Header
  250. onRightPress={() => {
  251. navigation.navigate("searchFilters")
  252. }}
  253. onLeftPress={() => noop()}
  254. leftTx="spaceListScreen.searchSpaces"
  255. rightTx="spaceListScreen.filter"
  256. style={HEADER}
  257. leftTextStyle={HEADER_LEFT_TEXT}
  258. rightTextStyle={HEADER_RIGHT_TEXT}
  259. />
  260. ),
  261. })
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement