Skip to content
This repository has been archived by the owner on Mar 12, 2020. It is now read-only.

Commit

Permalink
File sync viz on shared photo (#1232)
Browse files Browse the repository at this point in the history
* Move file-sync feature inside group feature, augment feed data with sync state

Signed-off-by: Aaron Sutula <[email protected]>

* Add lib for progress indicator

Signed-off-by: Aaron Sutula <[email protected]>

* wip

Signed-off-by: Aaron Sutula <[email protected]>

* Add total size logic

Signed-off-by: Aaron Sutula <[email protected]>

* Lint fixes

Signed-off-by: Aaron Sutula <[email protected]>

* fix tsc errors around GroupStatus

Signed-off-by: Aaron Sutula <[email protected]>

* Better progress indicator lib

Signed-off-by: Aaron Sutula <[email protected]>

* Display file sync error on shared photo

Signed-off-by: Aaron Sutula <[email protected]>
  • Loading branch information
asutula authored Jul 25, 2019
1 parent d570e5d commit 2fda65f
Show file tree
Hide file tree
Showing 22 changed files with 301 additions and 102 deletions.
8 changes: 1 addition & 7 deletions App/Components/like-and-comment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ import Icon from '@textile/react-native-icon'

import { color, spacing, textStyle } from '../styles'

const CONTAINER: ViewStyle = {
paddingLeft: spacing.screenEdge,
paddingRight: spacing.screenEdge,
paddingTop: spacing.screenEdge
}

const ICONS: ViewStyle = {
flexDirection: 'row'
}
Expand Down Expand Up @@ -56,7 +50,7 @@ const LikeAndComment = (props: Props) => {
(!hasLiked && numberLikes > 0) || (hasLiked && numberLikes > 1)
const displayCommentsCount = numberComments > 0
return (
<View style={[CONTAINER, likesAndCommentsContainerStyle]}>
<View style={likesAndCommentsContainerStyle}>
<View style={ICONS}>
{hasLiked && (
<Icon
Expand Down
50 changes: 47 additions & 3 deletions App/Components/photo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ import {
Dimensions,
Modal
} from 'react-native'
import ImageZoom from 'react-native-image-pan-zoom'
import { Circle } from 'react-native-progress'
import Icon from '@textile/react-native-icon'

import Message, { Props as MessageProps } from './message'
import ProgressiveImage from './ProgressiveImage'
import LikeAndComment, {
Props as LikeAndCommentProps
} from './like-and-comment'
import { spacing } from '../styles'
import { spacing, size, color, textStyle } from '../styles'
import Comments, { Props as CommentsProps } from './comments'
import ImageZoom from 'react-native-image-pan-zoom'
import { GroupStatus } from '../features/group/file-sync/models'

const CONTAINER: ViewStyle = {
paddingTop: spacing._016,
Expand All @@ -31,6 +34,8 @@ interface Props extends MessageProps, LikeAndCommentProps, CommentsProps {
photoId: string
fileIndex: number
photoWidth: number
syncStatus?: GroupStatus
displayError?: (message: string) => () => void
pinchZoom?: boolean
pinchHeight?: number
pinchWidth?: number
Expand Down Expand Up @@ -126,6 +131,11 @@ export default class Photo extends React.PureComponent<Props> {

renderSelection() {
// Just uses a touchable image, when touched will enable it's own modal in full screen
let progress: number | undefined
if (this.props.syncStatus) {
const { sizeComplete, sizeTotal } = this.props.syncStatus
progress = sizeComplete / sizeTotal
}
return (
<View style={CONTAINER}>
<Modal
Expand All @@ -142,7 +152,41 @@ export default class Photo extends React.PureComponent<Props> {
this.props.photoWidth,
this.props.photoWidth
)}
<LikeAndComment {...this.props} />
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: spacing.screenEdge,
paddingRight: spacing.screenEdge,
paddingTop: spacing.screenEdge
}}
>
<LikeAndComment {...this.props} />
{this.props.syncStatus && !this.props.syncStatus.error && (
<Circle
showsText={false}
size={size._024}
thickness={2}
progress={progress}
color={color.brandBlue}
/>
)}
{this.props.syncStatus && this.props.syncStatus.error && (
<TouchableOpacity
onPress={
this.props.displayError
? this.props.displayError(this.props.syncStatus.error.reason)
: undefined
}
>
<Icon
name="alert-circle"
size={size._024}
style={{ color: color.severe_3 }}
/>
</TouchableOpacity>
)}
</View>
<Comments {...this.props} />
</View>
)
Expand Down
13 changes: 8 additions & 5 deletions App/Redux/RootReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { reducer as textileEventsReducer } from './TextileEventsRedux'
import { groupReducer } from '../features/group'
import { photosReducer } from '../features/photos'
import { cafesReducer } from '../features/cafes'
import { fileSyncReducer } from '../features/file-sync'

const migrations: MigrationManifest = {
0: persistedState => {
Expand Down Expand Up @@ -360,14 +359,19 @@ const migrations: MigrationManifest = {
const state = persistedState as any
const { cafeSessions, ...rest } = state.account
return { ...state, account: rest }
},
23: persistedState => {
const state = persistedState as any
const { fileSync, ...rest } = state
return rest
}
}

const persistConfig: PersistConfig = {
key: 'primary',
storage: AsyncStorage,
version: 22,
whitelist: ['account', 'preferences', 'deviceLogs', 'fileSync'],
version: 23,
whitelist: ['account', 'preferences', 'deviceLogs'],
migrate: createMigrate(migrations, { debug: false }),
debug: false
}
Expand All @@ -386,8 +390,7 @@ const rootReducer = combineReducers({
textile: textileEventsReducer,
group: groupReducer,
photos: photosReducer,
cafes: cafesReducer,
fileSync: fileSyncReducer
cafes: cafesReducer
})

export default persistReducer(persistConfig, rootReducer)
2 changes: 0 additions & 2 deletions App/Redux/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { TextileEventsAction } from './TextileEventsRedux'
import { GroupAction } from '../features/group'
import { PhotosAction } from '../features/photos'
import { CafesAction } from '../features/cafes'
import { FileSyncAction } from '../features/file-sync'

export type RootState = StateType<typeof RootReducer> & PersistPartial
export type RootAction =
Expand All @@ -36,4 +35,3 @@ export type RootAction =
| GroupAction
| PhotosAction
| CafesAction
| FileSyncAction
29 changes: 22 additions & 7 deletions App/Sagas/TextileEventsSagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { ActionType, getType } from 'typesafe-actions'
import RNPushNotification from 'react-native-push-notification'
import Textile, {
EventSubscription,
FeedItemType,
ICafeSyncGroupStatus
FeedItemType
} from '@textile/react-native-sdk'
import Long from 'long'

import { toTypedNotification } from '../Services/Notifications'
import { logNewEvent } from './DeviceLogs'
Expand All @@ -28,7 +28,6 @@ import PhotoViewingActions, {
import { contactsActions, ContactsAction } from '../features/contacts'
import DeviceLogsActions, { DeviceLogsAction } from '../Redux/DeviceLogsRedux'
import { groupActions, GroupAction } from '../features/group'
import { fileSyncActions, FileSyncAction } from '../features/file-sync'
import AppConfig from '../Config/app-config'

function displayNotification(message: string, title?: string) {
Expand All @@ -49,7 +48,6 @@ function nodeEvents() {
| DeviceLogsAction
| NotificationsAction
| TextileEventsAction
| FileSyncAction
>(emitter => {
const subscriptions: EventSubscription[] = []
subscriptions.push(
Expand Down Expand Up @@ -161,17 +159,34 @@ function nodeEvents() {
)
subscriptions.push(
Textile.events.addSyncUpdateListener(status => {
emitter(fileSyncActions.syncUpdate(status))
const sizeComplete = Long.fromValue(status.sizeComplete).toNumber()
const sizeTotal = Long.fromValue(status.sizeTotal).toNumber()
const groupSizeComplete = Long.fromValue(
status.groupsSizeComplete
).toNumber()
const groupSizeTotal = Long.fromValue(status.groupsSizeTotal).toNumber()
const total = Math.max(sizeTotal, groupSizeTotal)
const { id, numComplete, numTotal } = status
emitter(
groupActions.fileSync.syncUpdate(
id,
numComplete,
numTotal,
groupSizeComplete,
total
)
)
})
)
subscriptions.push(
Textile.events.addSyncCompleteListener(status => {
emitter(fileSyncActions.syncComplete(status))
emitter(groupActions.fileSync.syncComplete(status.id))
})
)
subscriptions.push(
Textile.events.addSyncFailedListener(status => {
emitter(fileSyncActions.syncFailed(status))
const { id, errorId, error } = status
emitter(groupActions.fileSync.syncFailed(id, errorId, error))
})
)
return () => {
Expand Down
18 changes: 0 additions & 18 deletions App/features/file-sync/actions.ts

This file was deleted.

7 changes: 0 additions & 7 deletions App/features/file-sync/index.ts

This file was deleted.

35 changes: 0 additions & 35 deletions App/features/file-sync/reducer.ts

This file was deleted.

3 changes: 2 additions & 1 deletion App/features/group/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { feedActions as feed } from './feed'
import { addMessageActions as addMessage } from './add-message'
import { addPhotoActions as addPhoto } from './add-photo'
import { renameGroupActions as renameGroup } from './rename-group'
import { fileSyncActions as fileSync } from './file-sync'
import { ignoreActions as ignore } from './ignore'

export { feed, addMessage, addPhoto, renameGroup, ignore }
export { feed, addMessage, addPhoto, renameGroup, fileSync, ignore }
37 changes: 37 additions & 0 deletions App/features/group/file-sync/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { createAction } from 'typesafe-actions'

export const syncUpdate = createAction(
'group/file-sync/SYNC_UPDATE',
resolve => {
return (
groupId: string,
numberComplete: number,
numberTotal: number,
sizeComplete: number,
sizeTotal: number
) =>
resolve({ groupId, numberComplete, numberTotal, sizeComplete, sizeTotal })
}
)

export const syncComplete = createAction(
'group/file-sync/SYNC_COMPLETE',
resolve => {
return (groupId: string) => resolve({ groupId })
}
)

export const syncFailed = createAction(
'group/file-sync/SYNC_FAILED',
resolve => {
return (groupId: string, errorId: string, reason: string) =>
resolve({ groupId, errorId, reason })
}
)

export const clearStatus = createAction(
'group/file-sync/CLEAR_STATUS',
resolve => {
return (groupId: string) => resolve({ groupId })
}
)
11 changes: 11 additions & 0 deletions App/features/group/file-sync/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as fileSyncActions from './actions'
import fileSyncReducer, { FileSyncState, FileSyncAction } from './reducer'
import * as fileSyncSelectors from './selectors'

export {
fileSyncActions,
fileSyncReducer,
fileSyncSelectors,
FileSyncState,
FileSyncAction
}
10 changes: 10 additions & 0 deletions App/features/group/file-sync/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export interface GroupStatus {
numberComplete: number
numberTotal: number
sizeComplete: number
sizeTotal: number
error?: {
id: string
reason: string
}
}
Loading

0 comments on commit 2fda65f

Please sign in to comment.