Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload with notifications #409

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/screens/connect-wallet/create-did-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { NativeStackScreenProps } from '@react-navigation/native-stack'
import Toast from 'react-native-toast-message'
import { HDKEY } from '@functionland/fula-sec'
import { useSetRecoilState } from 'recoil'
import notifee from '@notifee/react-native'
import notifee, { AndroidColor } from '@notifee/react-native'

import * as Keychain from '../../utils/keychain'
import { Header, HeaderArrowBack } from '../../components/header'
Expand Down Expand Up @@ -57,6 +57,8 @@ export const CreateDIDScreen: React.FC<Props> = ({ navigation, route }) => {
pressAction: {
id: 'default'
},
colorized: true,
color: AndroidColor.RED,
ongoing: true,
asForegroundService: true,
channelId: 'sticky'
Expand Down
25 changes: 24 additions & 1 deletion app/screens/image-gallery-viewer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { GalleryImage } from './gallery-image'
import { palette } from '../../theme'
import LinearGradient from 'react-native-linear-gradient'
import { SyncService } from '../../services'
import { uploadAssets } from '../../services/sync-service'

interface ImageGalleryViewerScreenProps {
navigation: NavigationProp<RootStackParamList>
Expand Down Expand Up @@ -274,7 +275,29 @@ export const ImageGalleryViewerScreen: React.FC<
])
}, [asset])

const uploadToBox = async () => {
async function uploadToBox() {
//Ignore asset greater than 200 MB
if (!asset?.fileSize || asset.fileSize > 200 * 1000 * 1000) {
Toast.show({
type: 'info',
text1: 'Large asset!',
text2: 'Unable to upload assets greater than 200 MB for now!',
position: 'top',
bottomOffset: 40,
})
return
}
setLoading(true)
try {
await uploadAssets([asset])
} catch (err) {
console.error(err)
} finally {
setLoading(false)
}
}

const uploadToBoxOld = async () => {
if (asset?.syncStatus === SyncStatus.NOTSYNCED && !asset?.isDeleted) {
//Ignore asset greater than 200 MB
if (!asset?.fileSize || asset.fileSize > 200 * 1000 * 1000) {
Expand Down
183 changes: 171 additions & 12 deletions app/services/sync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import BackgroundJob, {
import { fula, chainApi } from '@functionland/react-native-fula'
// import { TaggedEncryption } from '@functionland/fula-sec'
import { AssetEntity } from '../realmdb/entities'
import { SyncStatus } from '../types'
import { Asset, SyncStatus } from '../types'
import { Assets, Boxs, FolderSettings } from './localdb/index'
import * as Constants from '../utils/constants'
import { Helper, DeviceUtils, KeyChain } from '../utils'
import { ApiPromise } from '@polkadot/api'
import * as helper from '../utils/helper'
import Toast from 'react-native-toast-message'
import notifee, { AndroidColor } from '@notifee/react-native'
import { createForegroundTask } from './foreground'

type TaskParams = {
callback?: (success: boolean, assetId: string, error?: Error) => void
Expand Down Expand Up @@ -61,6 +64,10 @@ const uploadAssetBackgroundTask = async (taskParameters?: TaskParams) => {
}
console.log('uploadAssetBackgroundTask fulaConfig')
console.log(fulaConfig)
let resolveUploadCompleted = () => {}
const uploadCompleted = new Promise<void>(resolve => {
resolveUploadCompleted = resolve
})
for (let index = 0; index < assets?.length; index++) {
const asset = assets[index]
console.log('uploadAssetBackgroundTask asset...', index)
Expand All @@ -71,18 +78,40 @@ const uploadAssetBackgroundTask = async (taskParameters?: TaskParams) => {
continue
}

// Prepare task notification message
if (BackgroundJob.isRunning()) {
await BackgroundJob.updateNotification({
taskTitle: `Uploading asset #${index + 1}/${assets?.length}`,
taskDesc: `Syncing your assets ...`,
progressBar: {
// // Prepare task notification message
// if (BackgroundJob.isRunning()) {
// await BackgroundJob.updateNotification({
// taskTitle: `Uploading asset #${index + 1}/${assets?.length}`,
// taskDesc: `Syncing your assets ...`,
// progressBar: {
// max: assets?.length,
// value: index,
// indeterminate: assets?.length == 1,
// },
// })
// }

// Show notification
await notifee.requestPermission()
await notifee.createChannel({
id: 'sync',
name: "Sync Status"
})
notifee.registerForegroundService(() => uploadCompleted)
await notifee.displayNotification({
title: 'Sync in progress...',
subtitle: `Syncing ${assets?.length} photo${assets?.length > 1 ? 's': ''}`,
android: {
channelId: 'sync',
groupSummary: true,
groupId: 'syncGroup',
asForegroundService: true,
progress: {
max: assets?.length,
value: index,
indeterminate: assets?.length == 1,
},
})
}
current: index
}
}
})

// Prepare the filepath and filename
const _filePath = asset.uri?.split('file:')[1]
Expand All @@ -93,6 +122,17 @@ const uploadAssetBackgroundTask = async (taskParameters?: TaskParams) => {
? slashSplit[slashSplit?.length - 1]
: 'unknown' + index
}
await notifee.displayNotification({
title: 'Uploading Photo',
subtitle: `File ${filename} in progress...`,
android: {
channelId: 'sync',
groupId: 'syncGroup',
progress: {
indeterminate: true
}
}
})
// Upload file to the WNFS
if (_filePath) {
const cid = await fula.writeFile(
Expand All @@ -118,6 +158,7 @@ const uploadAssetBackgroundTask = async (taskParameters?: TaskParams) => {
}
}
}
resolveUploadCompleted()
try {
//TODO: Replicate request should be sent to blockchain
let storedCids = await fula.listRecentCidsAsString()
Expand Down Expand Up @@ -219,6 +260,124 @@ const downloadAssetsBackgroundTask = async (taskParameters?: TaskParams) => {
await BackgroundJob.stop()
}
}

let [successCount, failCount] = [0, 0]

export async function uploadAssets(assets: Asset[]) {
if (!assets || assets.length == 0) {
return
}
const uploadAndNotifyResult = async asset => {
try {
await uploadAsset(asset)
successCount++
await notifee.displayNotification({
title: `${asset.filename}`,
subtitle: 'uploaded',
// body: ``,
android: {
channelId: 'syncStatus',
groupId: 'syncStatusGroup'
}
})
} catch (error) {
console.error(error)
failCount++
await notifee.displayNotification({
title: `${asset.filename}`,
subtitle: 'failed',
body: `Error: ${JSON.stringify(error)}`,
android: {
channelId: 'syncStatus',
groupId: 'syncStatusGroup'
}
})
}
await notifee.displayNotification({
id: 'statusSummary',
subtitle: `upload ${successCount ? `${successCount} succeeded` : '' }` +
`${successCount? ', ': ''}${failCount ? `${failCount} failed` : '' }`,
android: {
channelId: 'syncStatus',
groupSummary: true,
groupId: 'syncStatusGroup'
}
})
}
await notifee.requestPermission()
await notifee.createChannel({
id: 'sync',
name: 'Sync',
vibration: false
})
await notifee.createChannel({
id: 'syncStatus',
name: 'Sync Status',
vibration: false
})
notifee.registerForegroundService(async notification => {
const uploads: Promise<void>[] = []
for (let index = 0; index < assets.length; index++) {
let asset = assets[index]
const remainingCount = assets.length - index
await notifee.displayNotification({
id: notification.id,
title: `Uploading ${remainingCount} photo${remainingCount > 1 ? 's': ''}`,
body: `${asset.filename} in progress`,
android: {
...notification.android,
progress: {
max: assets.length,
current: index
}
}
})
uploads.push(uploadAndNotifyResult(asset))
await Promise.all(uploads)
}
})

await notifee.displayNotification({
title: 'Upload started',
android: {
channelId: 'sync',
ongoing: true,
asForegroundService: true,
colorized: true,
color: AndroidColor.NAVY
}
})
}

async function uploadAsset(asset: Asset) {
Toast.show({
type: 'info',
text1: asset.filename,
text2: 'uploadingg',
position: 'top',
bottomOffset: 40,
})
await new Promise(resolve => setTimeout(resolve, 3000))
throw new Error('pfff')
// const filePath = asset.uri?.split('file:')[1]
// if (!filePath) {
// throw Error('Invalid asset uri')
// }
// const cid = await fula.writeFile(`${Constants.FOTOS_WNFS_ROOT}/${asset.filename}`, filePath)
// console.log('----------')
// console.log(cid)
// console.log('----------')
// await Helper.storeFulaRootCID(cid)
// //Update asset record in database
// const newAsset = {
// id: asset.id,
// cid: cid,
// syncDate: new Date(),
// syncStatus: SyncStatus.SYNCED,
// }
// Assets.addOrUpdate([newAsset])
}

// /**
// * You need to make sure the box addresses are added and then call this method
// * @param options
Expand Down