diff --git a/.env.production b/.env.production index 06f4fbc..b6b2257 100644 --- a/.env.production +++ b/.env.production @@ -1,7 +1,7 @@ -# API_URL=https://tasks-api.rwsbank.com.ua -# SOCKET_URL=https://tasks-api.rwsbank.com.ua -# ONE_SIGNAL_KEY=5e1a5e18-33e5-4ed3-8423-45b1abc354c6 +API_URL=https://tasks-api.rwsbank.com.ua +SOCKET_URL=https://tasks-api.rwsbank.com.ua +ONE_SIGNAL_KEY=5e1a5e18-33e5-4ed3-8423-45b1abc354c6 -API_URL=https://taskme-api.work-jetup.site -SOCKET_URL=https://taskme-api.work-jetup.site -ONE_SIGNAL_KEY=8b9066f5-8c3f-49f7-bef4-c5ab621f9d27 +# API_URL=https://taskme-api.work-jetup.site +# SOCKET_URL=https://taskme-api.work-jetup.site +# ONE_SIGNAL_KEY=8b9066f5-8c3f-49f7-bef4-c5ab621f9d27 diff --git a/android/app/build.gradle b/android/app/build.gradle index eafb442..f4b88ec 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -26,7 +26,7 @@ android { applicationId "com.app.task_me" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 228 + versionCode 229 versionName "2.3" resValue "string", "build_config_package", "com.app.task_me" } diff --git a/ios/taskme2.xcodeproj/project.pbxproj b/ios/taskme2.xcodeproj/project.pbxproj index a4be64c..2ac31f7 100644 --- a/ios/taskme2.xcodeproj/project.pbxproj +++ b/ios/taskme2.xcodeproj/project.pbxproj @@ -753,7 +753,10 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; @@ -768,7 +771,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = taskme2/taskme2Stage.Debug.entitlements; - CURRENT_PROJECT_VERSION = 28; + CURRENT_PROJECT_VERSION = 29; DEVELOPMENT_TEAM = HQ3J3TDPR2; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -1036,7 +1039,10 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; @@ -1052,7 +1058,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = taskme2/taskme2Stage.Release.entitlements; - CURRENT_PROJECT_VERSION = 28; + CURRENT_PROJECT_VERSION = 29; DEVELOPMENT_TEAM = HQ3J3TDPR2; HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -1332,7 +1338,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = taskme2/taskme2.entitlements; - CURRENT_PROJECT_VERSION = 28; + CURRENT_PROJECT_VERSION = 29; DEVELOPMENT_TEAM = HQ3J3TDPR2; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -1470,7 +1476,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = taskme2/taskme2.entitlements; - CURRENT_PROJECT_VERSION = 28; + CURRENT_PROJECT_VERSION = 29; DEVELOPMENT_TEAM = HQ3J3TDPR2; HEADER_SEARCH_PATHS = ( "$(inherited)", @@ -1674,7 +1680,10 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; @@ -1752,7 +1761,10 @@ "-DFOLLY_MOBILE=1", "-DFOLLY_USE_LIBCPP=1", ); - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; diff --git a/src/api/auth/requests.ts b/src/api/auth/requests.ts index 44efc14..a554d90 100644 --- a/src/api/auth/requests.ts +++ b/src/api/auth/requests.ts @@ -26,8 +26,6 @@ export const resetSessionReq = ( return axiosInstance.post('/app/auth/refresh-token', params) } -export const signOut = ( - params: ILogoutPayload, -): ApiResponse => { - return http.post('auth/logout', params) +export const signOut = (params: ILogoutPayload): ApiResponse => { + return http.post('auth/logout', params) } diff --git a/src/api/calls/requests.ts b/src/api/calls/requests.ts index 38117d9..a8d176a 100644 --- a/src/api/calls/requests.ts +++ b/src/api/calls/requests.ts @@ -23,6 +23,11 @@ export const iceCandidateReq = (payload: IIceCandidatePayload) => { export const cancelCallReq = (payload: ICancelCallPayload) => { return api.post('calls/cancel', payload, {}, '') } + +export const rejectCallReq = (payload: ICancelCallPayload) => { + return api.post('calls/reject', payload, {}, '') +} + export const finishCallReq = (payload: IFinishCallPayload) => { return api.post('calls/finish', payload, {}, '') } @@ -31,7 +36,7 @@ export const getCallsListReq = (params: any) => { return api.get('calls', params, '') } -export const deleteCallHistoryReq = (callId: number) => { +export const deleteCallHistoryReq = (callId: string) => { return api.delete(`calls/history/${callId}`, null, '') } diff --git a/src/modules/calls/core/stop-call.ts b/src/modules/calls/core/stop-call.ts index 63a2e3e..c8e311c 100644 --- a/src/modules/calls/core/stop-call.ts +++ b/src/modules/calls/core/stop-call.ts @@ -1,6 +1,7 @@ import { finishCallReq } from '@/api/calls/requests' import { CallDataStore, ICallStreamsStore } from '../hooks' import { MediaStream } from 'react-native-webrtc' +import inCallManager from 'react-native-incall-manager' export class StopCall { constructor( @@ -20,9 +21,17 @@ export class StopCall { await finishCallReq({ callId: this.callDataStore.callId, }).catch(console.log) - // inCallManager.stop() + this.peerConnection.close() this.stopStreams() + + try { + inCallManager.stopRingback() + inCallManager.stopRingtone() + inCallManager.stop() + } catch (e) { + console.log('incallmeneger', e) + } } private stopStreams() { diff --git a/src/modules/calls/screens/call/index.tsx b/src/modules/calls/screens/call/index.tsx index 2dbc1bd..4c81e39 100644 --- a/src/modules/calls/screens/call/index.tsx +++ b/src/modules/calls/screens/call/index.tsx @@ -93,7 +93,7 @@ export const CallScreen = () => { ), [CallMod.Finished]: ( diff --git a/src/modules/calls/services/call.service.ts b/src/modules/calls/services/call.service.ts index 6da0fb9..124caf5 100644 --- a/src/modules/calls/services/call.service.ts +++ b/src/modules/calls/services/call.service.ts @@ -8,7 +8,14 @@ import { StopCall } from '../core/stop-call' import { cancelCallReq } from '@/api/calls/requests' import { RTCSessionDescription } from 'react-native-webrtc' import { callKeepService } from './callkeep' +import inCallManager from 'react-native-incall-manager' + class CallService extends CallRoot { + constructor() { + super() + inCallManager.stopRingback() + } + public async proccesIncome(data: any) { const peerConnection = await peerConnectionService.createIns() @@ -32,6 +39,7 @@ class CallService extends CallRoot { public async processStart(targetUserId: number) { try { + inCallManager.start({ media: 'audio', ringback: '_BUNDLE_' }) const peerConnection = await peerConnectionService.createIns() useCallDataStore.getState().startCall(targetUserId, peerConnection) NavigationService.navigate(RouteKey.Call, {}) @@ -53,15 +61,27 @@ class CallService extends CallRoot { public async finishCall() { useCallDataStore.setState(useCallDataStore.getInitialState()) NavigationService.goBack() + callKeepService.stop() } public async cancel() { + try { + inCallManager.stopRingback() + } catch (e) {} await cancelCallReq({ callId: useCallDataStore.getState().callId, }).catch(console.log) new StopCall(useCallDataStore.getState, callsStreamsCtr).stop() useCallDataStore.setState(useCallDataStore.getInitialState()) + callKeepService.stop() + NavigationService.goBack() + } + + public async onRejectedByAnotherUser() { + inCallManager.stopRingback() + useCallDataStore.setState(useCallDataStore.getInitialState()) + callKeepService.stop() NavigationService.goBack() } } diff --git a/src/modules/calls/services/callkeep/callkeep-root.service.ts b/src/modules/calls/services/callkeep/callkeep-root.service.ts index 54ba796..9d46a27 100644 --- a/src/modules/calls/services/callkeep/callkeep-root.service.ts +++ b/src/modules/calls/services/callkeep/callkeep-root.service.ts @@ -1,9 +1,14 @@ -import { getCallReq, getIncomeDataReq } from '@/api/calls/requests' +import { + getCallReq, + getIncomeDataReq, + rejectCallReq, +} from '@/api/calls/requests' import RNCallKeep from 'react-native-callkeep' import { CallStatus, appEvents } from '@/shared' import { DeviceInfoService } from '@/services/system' import { CallRoot } from '../call-root.service' import { useLocalStream } from '../../hooks' +import { callService } from '../call.service' export class CallKeepRootService extends CallRoot { protected accountInited = false @@ -86,7 +91,7 @@ export class CallKeepRootService extends CallRoot { const { data: call } = await getCallReq(data.callUUID) if (call.status !== CallStatus.New) { appEvents.emit('openInfoModal', { - title: 'Звінок вже завершився', + title: 'Дзвінок вже завершився', message: 'Ініціатор скасував виклик або виклик був прийнятий на іншому девайсі', }) @@ -111,8 +116,12 @@ export class CallKeepRootService extends CallRoot { await getIncomeDataReq(payload.callUUID, id) } - protected async onEnd() { - console.log('onend') + protected async onEnd({ callUUID }) { + if (!this.store.callId) { + await rejectCallReq({ + callId: callUUID, + }) + } } protected async changeMuted({ muted }) { @@ -135,7 +144,9 @@ export class CallKeepRootService extends CallRoot { } public async stop() { - RNCallKeep.endCall(this.store.callId) + if (this.store.callId) { + RNCallKeep.endCall(this.store.callId) + } RNCallKeep.endAllCalls() } diff --git a/src/modules/calls/services/calls-events.service.ts b/src/modules/calls/services/calls-events.service.ts index 3e8011f..9c76e64 100644 --- a/src/modules/calls/services/calls-events.service.ts +++ b/src/modules/calls/services/calls-events.service.ts @@ -35,12 +35,14 @@ class CallsEventsService extends CallRoot { }) socketEvents.on('calls/answered-by-another-device', async data => { - console.log('calls/answered-by-another-device', data) const deviceId = await DeviceInfoService.getDeviceUniqueId() if (deviceId !== data.deviceUuid) { RNCallKeep.endAllCalls() } }) + socketEvents.on('calls/rejected', async () => { + callService.onRejectedByAnotherUser() + }) } private proccessIceCandidates() { diff --git a/src/modules/calls/smart-components/call-swipable-row-card.smart-component.tsx b/src/modules/calls/smart-components/call-swipable-row-card.smart-component.tsx index 8620bdb..dd953d9 100644 --- a/src/modules/calls/smart-components/call-swipable-row-card.smart-component.tsx +++ b/src/modules/calls/smart-components/call-swipable-row-card.smart-component.tsx @@ -10,7 +10,7 @@ import { deleteCallHistoryReq } from '@/api/calls/requests' import { callService } from '../services' interface IProps { - id: number + id: string callerFullName: string imageUrl?: string callStatus: CallTypesEnum @@ -32,7 +32,7 @@ export const CallSwipableRowCardSmart: FC = props => { } const handlePressCard = () => { - nav.navigate(RouteKey.ContactDetail, { contactId: props.id }) + nav.navigate(RouteKey.ContactDetail, { contactId: props.targetUserId }) } const handlePressCall = () => { diff --git a/src/modules/root/index.tsx b/src/modules/root/index.tsx index 530f974..1696dff 100644 --- a/src/modules/root/index.tsx +++ b/src/modules/root/index.tsx @@ -39,8 +39,6 @@ import { StyleSheet } from 'react-native' import { PartialTheme } from '@/shared/themes/interfaces' import { useAppBadge, useAppSocketListener, useNetConnect } from './hooks' import { PreviewFileModal, LoaderModal } from '@/shared/components/modals' -import { IncomingCallWidget } from '../calls/widgets' -import '@/modules/calls/core/call-events-listener' export const Navigation: FC = () => { const activeModule = useSelector(selectActiveNavigationModule) diff --git a/src/services/domain/auth.service.ts b/src/services/domain/auth.service.ts index 6f79488..5c5d5f9 100644 --- a/src/services/domain/auth.service.ts +++ b/src/services/domain/auth.service.ts @@ -142,7 +142,11 @@ const logout = async (refreshToken: string) => { try { const isSignedOutOnline = await accManager.signOutOnline.bind( accManager, - )({ refreshToken }) + { + refreshToken, + deviceUuid: await DeviceInfoService.getDeviceUniqueId(), + }, + )() await onLogout() if (!isSignedOutOnline) diff --git a/src/services/system/real-time.service.ts b/src/services/system/real-time.service.ts index 5c12914..39560f0 100644 --- a/src/services/system/real-time.service.ts +++ b/src/services/system/real-time.service.ts @@ -19,8 +19,6 @@ export class SocketIo { secure: true, reconnectionAttempts: 10, auth(cb) { - const token = store()?.getState()?.auth?.accessToken - console.log('token', token) cb({ accessToken: store()?.getState()?.auth?.accessToken }) }, }) @@ -125,6 +123,7 @@ export class SocketIo { this._onSocketSendEvent('call/ICEcandidate') this._onSocketSendEvent('call/canceled') this._onSocketSendEvent('calls/answered-by-another-device') + this._onSocketSendEvent('calls/rejected') this._on('error/join-user', async () => { await authService.refreshSession() diff --git a/src/shared/dto/account.dtos.ts b/src/shared/dto/account.dtos.ts index 9e37c16..84ea01d 100644 --- a/src/shared/dto/account.dtos.ts +++ b/src/shared/dto/account.dtos.ts @@ -24,4 +24,5 @@ export class UpdateAccountPayloadDto { export class SignOutPayloadDto { refreshToken: string + deviceUuid?: string } diff --git a/src/shared/events/index.ts b/src/shared/events/index.ts index d0cbf03..f02c623 100644 --- a/src/shared/events/index.ts +++ b/src/shared/events/index.ts @@ -254,6 +254,7 @@ export type SocketEvents = { 'calls/answered-by-another-device': { deviceUuid: string } + 'calls/rejected': {} } export const appEvents = new Events()