Browse Source

master (#18)

Co-authored-by: YaroslavBerkuta <yaroslavberkuta@gmail.com>
Co-authored-by: Vitalik <vitalik.yatsenko@jetup.team>
Co-authored-by: Oksana Stepanenko <oksana.stepanenko@jetup.team>
Reviewed-on: #18
pull/21/head
Vitalik Yatsenko 9 months ago
parent
commit
0a2fa97034
  1. 2
      android/app/build.gradle
  2. 36
      android/app/src/main/AndroidManifest.xml
  3. 7
      android/app/src/main/file_viewer_provider_paths.xml
  4. 2
      android/app/src/main/java/com/taskme2/MainApplication.java
  5. 2
      android/build.gradle
  6. 5
      android/settings.gradle
  7. 6
      ios/Podfile.lock
  8. 10
      ios/taskme2.xcodeproj/project.pbxproj
  9. 15
      package-lock.json
  10. 2
      package.json
  11. 2
      src/App.tsx
  12. 8
      src/api/auth/requests.ts
  13. 4
      src/api/http.service.ts
  14. 5
      src/modules/root/hooks/use-app-badge.hook.ts
  15. 2
      src/modules/root/smart-components/fancybox.smart-component.tsx
  16. 44
      src/modules/tasks/hooks/use-task-list-events.hook.ts
  17. 25
      src/services/domain/auth.service.ts
  18. 31
      src/services/system/fs.service.ts
  19. 1
      src/services/system/real-time.service.ts
  20. 8
      src/shared/components/elements/avatar.component.tsx
  21. 2
      src/shared/components/elements/index.ts
  22. 10
      src/shared/components/plugins/chat/chat-item-file.component.tsx
  23. 8
      src/shared/components/plugins/chat/chat-item-image.component.tsx
  24. 27
      src/shared/enums/file-type.enum.ts
  25. 5
      src/shared/events/index.ts
  26. 28
      src/shared/helpers/fingerprint.helper.ts
  27. 4
      src/shared/helpers/fs.helpers.ts
  28. 11
      src/shared/helpers/tranposition-cipher.helper.ts

2
android/app/build.gradle

@ -25,7 +25,7 @@ android { @@ -25,7 +25,7 @@ android {
applicationId "com.app.task_me"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 215
versionCode 217
versionName "2.3"
resValue "string", "build_config_package", "com.app.task_me"
}

36
android/app/src/main/AndroidManifest.xml

@ -57,5 +57,39 @@ @@ -57,5 +57,39 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="com.vinzscam.reactnativefileviewer.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_viewer_provider_paths"
/>
</provider>
</application>
</manifest>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="application/pdf" />
</intent>
</queries>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="text/plain" />
</intent>
</queries>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="application/msword" />
</intent>
</queries>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
</intent>
</queries>
</manifest>

7
android/app/src/main/file_viewer_provider_paths.xml

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="files" path="/" />
<external-files-path name="external_files" path="" />
<external-path name="external" path="." />
<cache-path name="cache" path="/" />
</paths>

2
android/app/src/main/java/com/taskme2/MainApplication.java

@ -24,7 +24,7 @@ public class MainApplication extends Application implements ReactApplication { @@ -24,7 +24,7 @@ public class MainApplication extends Application implements ReactApplication {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
// packages.add();
return packages;
}

2
android/build.gradle

@ -9,6 +9,8 @@ buildscript { @@ -9,6 +9,8 @@ buildscript {
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
ndkVersion = "23.1.7779620"
pdfViewerVersion = "3.2.0-beta.1"
pdfViewerRepo = "com.github.mhiew"
}
repositories {
google()

5
android/settings.gradle

@ -4,4 +4,7 @@ include ':app' @@ -4,4 +4,7 @@ include ':app'
includeBuild('../node_modules/@react-native/gradle-plugin')
include ':react-native-config'
project(':react-native-config').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-config/android')
project(':react-native-config').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-config/android')
include ':react-native-file-viewer'
project(':react-native-file-viewer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-file-viewer/android')

6
ios/Podfile.lock

@ -571,6 +571,8 @@ PODS: @@ -571,6 +571,8 @@ PODS:
- React-Core
- SDWebImage (~> 5.11.1)
- SDWebImageWebPCoder (~> 0.8.4)
- RNFileViewer (2.1.5):
- React-Core
- RNFS (2.20.0):
- React-Core
- RNGestureHandler (2.14.0):
@ -710,6 +712,7 @@ DEPENDENCIES: @@ -710,6 +712,7 @@ DEPENDENCIES:
- "RNCPicker (from `../node_modules/@react-native-picker/picker`)"
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNFastImage (from `../node_modules/react-native-fast-image`)
- RNFileViewer (from `../node_modules/react-native-file-viewer`)
- RNFS (from `../node_modules/react-native-fs`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
@ -874,6 +877,8 @@ EXTERNAL SOURCES: @@ -874,6 +877,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-device-info"
RNFastImage:
:path: "../node_modules/react-native-fast-image"
RNFileViewer:
:path: "../node_modules/react-native-file-viewer"
RNFS:
:path: "../node_modules/react-native-fs"
RNGestureHandler:
@ -979,6 +984,7 @@ SPEC CHECKSUMS: @@ -979,6 +984,7 @@ SPEC CHECKSUMS:
RNCPicker: b18aaf30df596e9b1738e7c1f9ee55402a229dca
RNDeviceInfo: db5c64a060e66e5db3102d041ebe3ef307a85120
RNFastImage: 5c9c9fed9c076e521b3f509fe79e790418a544e8
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
RNGestureHandler: 32a01c29ecc9bb0b5bf7bc0a33547f61b4dc2741
RNImageCropPicker: d9616a0cb9b72e8551ff94a7a5021fbd29050aa5

10
ios/taskme2.xcodeproj/project.pbxproj

@ -726,7 +726,7 @@ @@ -726,7 +726,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = taskme2/taskme2Stage.Release.entitlements;
CURRENT_PROJECT_VERSION = 9;
CURRENT_PROJECT_VERSION = 12;
DEVELOPMENT_TEAM = HQ3J3TDPR2;
INFOPLIST_FILE = taskme2/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Task me ;)";
@ -905,8 +905,8 @@ @@ -905,8 +905,8 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = taskme2/taskme2.entitlements;
CURRENT_PROJECT_VERSION = 9;
DEVELOPMENT_TEAM = HQ3J3TDPR2;
CURRENT_PROJECT_VERSION = 12;
DEVELOPMENT_TEAM = VCUZPZ9254;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = taskme2/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Task me ;)";
@ -942,8 +942,8 @@ @@ -942,8 +942,8 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = taskme2/taskme2.entitlements;
CURRENT_PROJECT_VERSION = 9;
DEVELOPMENT_TEAM = HQ3J3TDPR2;
CURRENT_PROJECT_VERSION = 12;
DEVELOPMENT_TEAM = VCUZPZ9254;
INFOPLIST_FILE = taskme2/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Task me ;)";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";

15
package-lock.json generated

@ -32,6 +32,7 @@ @@ -32,6 +32,7 @@
"events": "^3.3.0",
"ffmpeg-kit-react-native": "^5.1.0",
"jet-tools": "^1.3.0",
"js-base64": "^3.7.6",
"lodash": "^4.17.21",
"mime": "^3.0.0",
"moment": "^2.29.4",
@ -53,6 +54,7 @@ @@ -53,6 +54,7 @@
"react-native-exception-handler": "^2.10.10",
"react-native-expire-storage": "^0.0.3",
"react-native-fast-image": "^8.6.3",
"react-native-file-viewer": "^2.1.5",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "^2.11.0",
"react-native-gifted-chat": "^2.4.0",
@ -12767,6 +12769,11 @@ @@ -12767,6 +12769,11 @@
"@sideway/pinpoint": "^2.0.0"
}
},
"node_modules/js-base64": {
"version": "3.7.6",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.6.tgz",
"integrity": "sha512-NPrWuHFxFUknr1KqJRDgUQPexQF0uIJWjeT+2KjEePhitQxQEx5EJBG1lVn5/hc8aLycTpXrDOgPQ6Zq+EDiTA=="
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -15644,6 +15651,14 @@ @@ -15644,6 +15651,14 @@
"react-native": ">=0.60.0"
}
},
"node_modules/react-native-file-viewer": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/react-native-file-viewer/-/react-native-file-viewer-2.1.5.tgz",
"integrity": "sha512-MGC6sx9jsqHdefhVQ6o0akdsPGpkXgiIbpygb2Sg4g4bh7v6K1cardLV1NwGB9A6u1yICOSDT/MOC//9Ez6EUg==",
"peerDependencies": {
"react-native": ">=0.47"
}
},
"node_modules/react-native-flipper": {
"version": "0.164.0",
"resolved": "https://registry.npmjs.org/react-native-flipper/-/react-native-flipper-0.164.0.tgz",

2
package.json

@ -42,6 +42,7 @@ @@ -42,6 +42,7 @@
"events": "^3.3.0",
"ffmpeg-kit-react-native": "^5.1.0",
"jet-tools": "^1.3.0",
"js-base64": "^3.7.6",
"lodash": "^4.17.21",
"mime": "^3.0.0",
"moment": "^2.29.4",
@ -63,6 +64,7 @@ @@ -63,6 +64,7 @@
"react-native-exception-handler": "^2.10.10",
"react-native-expire-storage": "^0.0.3",
"react-native-fast-image": "^8.6.3",
"react-native-file-viewer": "^2.1.5",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "^2.11.0",
"react-native-gifted-chat": "^2.4.0",

2
src/App.tsx

@ -2,7 +2,7 @@ import React, { FC, useEffect } from 'react' @@ -2,7 +2,7 @@ import React, { FC, useEffect } from 'react'
import { Provider } from 'react-redux'
import { Navigation } from './modules/root'
import store from './store'
import './services/system/reactron.service'
// import './services/system/reactron.service'
import { ThemeProvider } from './shared/themes'
// import Orientation from 'react-native-orientation-locker'
import { AppState, LogBox } from 'react-native'

8
src/api/auth/requests.ts

@ -23,7 +23,13 @@ export const finishLogin = ( @@ -23,7 +23,13 @@ export const finishLogin = (
export const resetSessionReq = (
params: IRefreshTokenPayload,
): ApiResponse<IAuthSuccessResponse> => {
return http.post<IAuthSuccessResponse>('auth/refresh-token', params)
return http.post<IAuthSuccessResponse>(
'auth/refresh-token',
params,
null,
null,
false,
)
}
export const signOut = (

4
src/api/http.service.ts

@ -7,6 +7,7 @@ import { authService } from '@/services/domain' @@ -7,6 +7,7 @@ import { authService } from '@/services/domain'
import { SetIsForbidden } from '@/store/shared'
import { simpleDispatch } from '@/store/store-helpers'
import { getErrorCode } from '@/shared/helpers'
import { UserFingerprintGenerator } from '@/shared/helpers/fingerprint.helper'
const store = () => GlobalContainerService.get('store')
@ -23,6 +24,9 @@ axiosInstance.interceptors.request.use((config: any) => { @@ -23,6 +24,9 @@ axiosInstance.interceptors.request.use((config: any) => {
if (token) {
config.headers['authorization'] = `Bearer ${token}`
}
config.headers['x-allow-lang'] =
UserFingerprintGenerator.generateUserFingerprint()
return config
})

5
src/modules/root/hooks/use-app-badge.hook.ts

@ -170,5 +170,10 @@ export const useAppBadge = () => { @@ -170,5 +170,10 @@ export const useAppBadge = () => {
permissions,
])
useSocketListener('task/hard-delete-task', decreaseTasksCountIfNeed, [
account,
permissions,
])
useSocketListener('user/change-permissions', onNeedReloadTasksCount, [])
}

2
src/modules/root/smart-components/fancybox.smart-component.tsx

@ -13,7 +13,7 @@ export interface FancyboxProps { @@ -13,7 +13,7 @@ export interface FancyboxProps {
}
export const FancyboxSmart = () => {
const { styles, theme } = useTheme(createStyles)
const { styles } = useTheme(createStyles)
const [url, setUrl] = useState(null)
useEventsListener(

44
src/modules/tasks/hooks/use-task-list-events.hook.ts

@ -42,25 +42,38 @@ export const useTaskListEvents = (props: IProps) => { @@ -42,25 +42,38 @@ export const useTaskListEvents = (props: IProps) => {
_.some(props.items, item => _.includes(ids, item.id.toString()))
const onTaskDeleted = (data: { ids: (number | string)[] }) => {
const ids = data.ids.map(it => it.toString())
if (!checkListContainAnyItem(ids)) return
if (
props.taskFilterStatus === TaskStatus.Active ||
props.taskFilterStatus === TaskStatus.Finished
) {
const filteredItems = _.filter(
props.items,
item => !_.includes(ids, item.id.toString()),
)
props.setItems(filteredItems)
props.onAction('delete')
if (props.items.length === 1)
appEvents.emit('onLastTaskDeleted', {})
deleteTaskFromList(data)
}
}
const onTaskHardDeleted = (data: {
taskId: number
executorId: number
}) => {
deleteTaskFromList({ ids: [data.taskId] })
}
function deleteTaskFromList(data: { ids: (number | string)[] }) {
const ids = data.ids.map(it => it.toString())
if (!checkListContainAnyItem(ids)) return
const filteredItems = _.filter(
props.items,
item => !_.includes(ids, item.id.toString()),
)
props.setItems(filteredItems)
props.onAction('delete')
if (props.items.length === 1 || _.isEmpty(filteredItems))
appEvents.emit('onLastTaskDeleted', {})
}
// *********** APP EVENTS AND SOCKET SIGNALS HANDLERS *************
const onTaskChanged = (data: { ids: (number | string)[] }) => {
if (!checkListContainAnyItem(data.ids.map(it => it.toString()))) return
@ -316,7 +329,10 @@ export const useTaskListEvents = (props: IProps) => { @@ -316,7 +329,10 @@ export const useTaskListEvents = (props: IProps) => {
// ************************************************************
// ******** SOCKET SIGNALS LISTENERS **************************
useSocketListener('task/new-comment', onTaskNewComment, [props.items, account])
useSocketListener('task/new-comment', onTaskNewComment, [
props.items,
account,
])
useSocketListener('task/new-task', onNewTask, [props.items])
@ -326,6 +342,8 @@ export const useTaskListEvents = (props: IProps) => { @@ -326,6 +342,8 @@ export const useTaskListEvents = (props: IProps) => {
useSocketListener('task/delete-task', onDeleteTask, [props.items])
useSocketListener('task/hard-delete-task', onTaskHardDeleted, [props.items])
useSocketListener('task/read', onTaskRead, [props.items])
useSocketListener('task/read-docs', onTaskDocumentsRead, [props.items])

25
src/services/domain/auth.service.ts

@ -160,18 +160,23 @@ const dropTokens = async () => { @@ -160,18 +160,23 @@ const dropTokens = async () => {
}
const refreshSession = async (refreshToken?: string) => {
let token = refreshToken
if (!token) {
const existTokens = await getTokensFromStore()
token = existTokens?.refreshToken
}
try {
let token = refreshToken
if (!token) {
const existTokens = await getTokensFromStore()
token = existTokens?.refreshToken
}
if (!token) return
if (!token) throw new Error('Refresh token isnt exist')
const { data } = await resetSessionReq({
refreshToken: token,
})
await saveTokens(data)
const { data } = await resetSessionReq({
refreshToken: token,
})
await saveTokens(data)
} catch (e) {
console.log('Error refresh session')
throw e
}
}
const getTokensFromStore = async () => {

31
src/services/system/fs.service.ts

@ -1,11 +1,12 @@ @@ -1,11 +1,12 @@
import { Alert, Platform } from 'react-native'
import { appEvents, IFile } from '@/shared'
import { appEvents, FileType, IFile } from '@/shared'
import {
createUniqueFileName,
getFileExtension,
getFileName,
getFileUri,
getNameFromFileUrl,
getUrlExtension,
isAndroid,
isImage,
} from '@/shared/helpers'
@ -15,6 +16,8 @@ import mime from 'mime' @@ -15,6 +16,8 @@ import mime from 'mime'
import { mediaPermissionsService } from './media-permissions.service'
import { saveToCameraRoll } from '@/services/system/camera-roll.service'
import Share from 'react-native-share'
import FileViewer from 'react-native-file-viewer'
import * as _ from 'lodash'
interface IWriteFileData {
content: string
fileName: string
@ -313,6 +316,31 @@ export const shareFileOutside = async ( @@ -313,6 +316,31 @@ export const shareFileOutside = async (
}
}
const validFileType = [FileType.DOC, FileType.DOCX, FileType.PDF]
const previewFile = (url: string) => {
try {
const extension = getUrlExtension(url)
if (!_.includes(validFileType, extension)) throw new Error()
const localFile = `${RNFS.DocumentDirectoryPath}/temporaryfile.${extension}`
const options = {
fromUrl: url,
toFile: localFile,
}
RNFS.downloadFile(options).promise.then(() =>
FileViewer.open(localFile),
)
} catch (error) {
appEvents.emit('openInfoModal', {
title: 'Сталась помилка!',
message: 'Цей тип файлу не підтримується!',
onPressOk: () => {},
})
}
}
export const fsService = {
getFileStat,
writeFile,
@ -325,4 +353,5 @@ export const fsService = { @@ -325,4 +353,5 @@ export const fsService = {
shareFile,
shareFileOutside,
createPath,
previewFile,
}

1
src/services/system/real-time.service.ts

@ -98,6 +98,7 @@ export class SocketIo { @@ -98,6 +98,7 @@ export class SocketIo {
this._onSocketSendEvent('task/update-task')
this._onSocketSendEvent('task/finish-task')
this._onSocketSendEvent('task/delete-task')
this._onSocketSendEvent('task/hard-delete-task')
this._onSocketSendEvent('task/read')
this._onSocketSendEvent('task/read-docs')
this._onSocketSendEvent('task/new-docs')

8
src/shared/components/elements/avatar.component.tsx

@ -1,13 +1,7 @@ @@ -1,13 +1,7 @@
import React, { FC } from 'react'
import { useTheme } from '@/shared/hooks/use-theme.hook'
import { PartialTheme } from '@/shared/themes/interfaces'
import {
StyleSheet,
TextStyle,
View,
ViewStyle,
Image,
} from 'react-native'
import { StyleSheet, TextStyle, View, ViewStyle, Image } from 'react-native'
import { Txt } from './txt.component'
interface AvatarProps {

2
src/shared/components/elements/index.ts

@ -10,4 +10,4 @@ export * from './not-found.component' @@ -10,4 +10,4 @@ export * from './not-found.component'
export * from './loading.component'
export * from './check-indicator.component'
export * from './remote-image.component'
export * from './selected-row-square-item.component'
export * from './selected-row-square-item.component'

10
src/shared/components/plugins/chat/chat-item-file.component.tsx

@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
import { fsService } from '@/services/system'
import { BYTES_IN_KILOBYTE } from '@/shared/consts'
import {
$size,
@ -14,6 +13,7 @@ import { StyleSheet, TouchableOpacity, View } from 'react-native' @@ -14,6 +13,7 @@ import { StyleSheet, TouchableOpacity, View } from 'react-native'
import { IconComponent, Txt } from '../../elements'
import { ChatItem } from './chat-item.component'
import { IChatMessage } from './interfaces'
import { fsService } from '@/services/system'
interface ChatItemFileProps extends IChatMessage {
onLongPress?: () => void
@ -35,18 +35,16 @@ export const ChatItemFile: FC<ChatItemFileProps> = props => { @@ -35,18 +35,16 @@ export const ChatItemFile: FC<ChatItemFileProps> = props => {
return `${convertToMegabytes(props.content.size)} MБ - `
}, [props.content.size])
const downloadFile = useCallback(() => {
const previewFile = useCallback(() => {
const content = props.content
fsService.shareFile(content?.fileUrl, content?.name)
fsService.previewFile(content?.fileUrl)
}, [props.content])
const iconName = getIconNameByExtension(props?.content?.fileUrl)
return (
<ChatItem {...props}>
<TouchableOpacity
style={styles.content}
onPress={() => downloadFile()}>
<TouchableOpacity style={styles.content} onPress={previewFile}>
<View style={styles.iconContainer}>
<IconComponent
color={theme?.chats?.message?.$fileIcon}

8
src/shared/components/plugins/chat/chat-item-image.component.tsx

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
import { appEvents } from '@/shared/events'
import { useTheme } from '@/shared/hooks'
import { PartialTheme } from '@/shared/themes/interfaces'
import React, { FC, useState } from 'react'
import React, { FC } from 'react'
import { StyleSheet, Dimensions, TouchableOpacity } from 'react-native'
import { RemoteImage } from '../../elements'
import { ChatItem } from './chat-item.component'
@ -17,12 +17,6 @@ interface ChatItemImageProps extends IChatMessage { @@ -17,12 +17,6 @@ interface ChatItemImageProps extends IChatMessage {
const width = (Dimensions.get('screen').width * 60) / 100
const calcHeight = (height: number, originWidth: number) => {
if (!height || !originWidth) return width
const persent = (height / originWidth) * 100
return (persent / 100) * width
}
export const ChatItemImage: FC<ChatItemImageProps> = props => {
const { styles } = useTheme(createStyles)
// const [height, setHeight] = useState(width)

27
src/shared/enums/file-type.enum.ts

@ -1,14 +1,15 @@ @@ -1,14 +1,15 @@
export enum FileType {
DOC = "doc",
GIF = "gif",
JPEG = "jpeg",
JPG = "jpg",
MP3 = "mp3",
MP4 = "mp4",
PDF = "pdf",
PNG = "png",
SVG = "svg",
TXT = "txt",
XLS = "xls",
ZIP = "zip"
}
DOC = 'doc',
GIF = 'gif',
JPEG = 'jpeg',
JPG = 'jpg',
MP3 = 'mp3',
MP4 = 'mp4',
PDF = 'pdf',
PNG = 'png',
SVG = 'svg',
TXT = 'txt',
XLS = 'xls',
ZIP = 'zip',
DOCX = 'docx',
}

5
src/shared/events/index.ts

@ -173,6 +173,11 @@ export type SocketEvents = { @@ -173,6 +173,11 @@ export type SocketEvents = {
executorId: number
events: Record<string, TaskEvent[]>
}
'task/hard-delete-task': {
taskId: number
executorId: number
events: Record<string, TaskEvent[]>
}
'task/finish-task': {
taskId: number
executorId: number

28
src/shared/helpers/fingerprint.helper.ts

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
import { Platform } from 'react-native'
import { TranspositionCipher } from './tranposition-cipher.helper'
import DeviceInfo from 'react-native-device-info'
export class UserFingerprintGenerator {
private static exist: string
static generateUserFingerprint(): string {
if (this.exist) return this.exist
const deviceId = DeviceInfo.getDeviceId()
const fingerprint = `deviceId:::${deviceId}|platform:::${
Platform.OS
}|brand:::${DeviceInfo.getBrand()}`
console.log('fingerprint', fingerprint)
const hashedFingerprint = this.hashFunction(fingerprint.trim())
this.exist = hashedFingerprint
return hashedFingerprint
}
private static hashFunction(input: string): string {
return TranspositionCipher.encrypt(input)
}
}

4
src/shared/helpers/fs.helpers.ts

@ -269,3 +269,7 @@ export const getIconNameByExtension = (name: string) => { @@ -269,3 +269,7 @@ export const getIconNameByExtension = (name: string) => {
if (iconByType) return iconByType
return 'others'
}
export const getUrlExtension = (link: string) => {
return link.split(/[#?]/)[0].split('.').pop().trim()
}

11
src/shared/helpers/tranposition-cipher.helper.ts

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
import { encode, decode } from 'js-base64'
export class TranspositionCipher {
static encrypt(message: string): string {
return encode(message)
}
static decrypt(encryptedMessage: string): string {
return decode(encryptedMessage)
}
}
Loading…
Cancel
Save