added Remember last viewed channel or thread on cold start feature (#7434)

* added last viewed feature

* added constants

* storing data in global table and added server col

* fixed stack screen"

* fixed values for crt

* fixed threadid store logic
This commit is contained in:
Harshal sanghvi
2023-07-21 13:39:26 +05:30
committed by GitHub
parent e98c893b33
commit b94eb1d4d8
6 changed files with 67 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {getActiveServerUrl} from '@app/init/credentials';
import {Tutorial} from '@constants';
import {GLOBAL_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
@@ -50,3 +51,29 @@ export const storeLastAskForReview = async (prepareRecordsOnly = false) => {
export const storeFirstLaunch = async (prepareRecordsOnly = false) => {
return storeGlobal(GLOBAL_IDENTIFIERS.FIRST_LAUNCH, Date.now(), prepareRecordsOnly);
};
export const storeLastViewedChannelIdAndServer = async (channelId: string) => {
const currentServerUrl = await getActiveServerUrl();
return storeGlobal(GLOBAL_IDENTIFIERS.LAST_VIEWED_CHANNEL, {
server_url: currentServerUrl,
channel_id: channelId,
}, false);
};
export const storeLastViewedThreadIdAndServer = async (threadId: string) => {
const currentServerUrl = await getActiveServerUrl();
return storeGlobal(GLOBAL_IDENTIFIERS.LAST_VIEWED_THREAD, {
server_url: currentServerUrl,
thread_id: threadId,
}, false);
};
export const removeLastViewedChannelIdAndServer = async () => {
return storeGlobal(GLOBAL_IDENTIFIERS.LAST_VIEWED_CHANNEL, null, false);
};
export const removeLastViewedThreadIdAndServer = async () => {
return storeGlobal(GLOBAL_IDENTIFIERS.LAST_VIEWED_THREAD, null, false);
};

View File

@@ -80,6 +80,8 @@ export const GLOBAL_IDENTIFIERS = {
FIRST_LAUNCH: 'firstLaunch',
LAST_ASK_FOR_REVIEW: 'lastAskForReview',
ONBOARDING: 'onboarding',
LAST_VIEWED_CHANNEL: 'lastViewedChannel',
LAST_VIEWED_THREAD: 'lastViewedThread',
};
export enum OperationType {

View File

@@ -5,12 +5,14 @@ import Emm from '@mattermost/react-native-emm';
import {Alert, AppState, DeviceEventEmitter, Linking, Platform} from 'react-native';
import {Notifications} from 'react-native-notifications';
import {switchToChannelById} from '@actions/remote/channel';
import {appEntry, pushNotificationEntry, upgradeEntry} from '@actions/remote/entry';
import {fetchAndSwitchToThread} from '@actions/remote/thread';
import LocalConfig from '@assets/config.json';
import {DeepLink, Events, Launch, PushNotification} from '@constants';
import DatabaseManager from '@database/manager';
import {getActiveServerUrl, getServerCredentials, removeServerCredentials} from '@init/credentials';
import {getOnboardingViewed} from '@queries/app/global';
import {getLastViewedChannelIdAndServer, getOnboardingViewed, getLastViewedThreadIdAndServer} from '@queries/app/global';
import {getThemeForCurrentTeam} from '@queries/servers/preference';
import {getCurrentUserId} from '@queries/servers/system';
import {queryMyTeams} from '@queries/servers/team';
@@ -172,6 +174,15 @@ const launchToHome = async (props: LaunchProps) => {
}
case Launch.Normal:
if (props.coldStart) {
const lastViewedChannel = await getLastViewedChannelIdAndServer();
const lastViewedThread = await getLastViewedThreadIdAndServer();
if (lastViewedThread && lastViewedThread.server_url === props.serverUrl && lastViewedThread.thread_id) {
fetchAndSwitchToThread(props.serverUrl!, lastViewedThread.thread_id);
} else if (lastViewedChannel && lastViewedChannel.server_url === props.serverUrl && lastViewedChannel.channel_id) {
switchToChannelById(props.serverUrl!, lastViewedChannel.channel_id);
}
appEntry(props.serverUrl!);
}
break;

View File

@@ -64,6 +64,16 @@ export const getFirstLaunch = async () => {
return records[0].value;
};
export const getLastViewedChannelIdAndServer = async () => {
const records = await queryGlobalValue(GLOBAL_IDENTIFIERS.LAST_VIEWED_CHANNEL)?.fetch();
return records?.[0]?.value;
};
export const getLastViewedThreadIdAndServer = async () => {
const records = await queryGlobalValue(GLOBAL_IDENTIFIERS.LAST_VIEWED_THREAD)?.fetch();
return records?.[0]?.value;
};
export const observeTutorialWatched = (tutorial: string) => {
const query = queryGlobalValue(tutorial);
if (!query) {

View File

@@ -5,6 +5,7 @@ import React, {useCallback, useEffect, useRef, useState} from 'react';
import {type LayoutChangeEvent, StyleSheet, View} from 'react-native';
import {type Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
import {storeLastViewedChannelIdAndServer, removeLastViewedChannelIdAndServer} from '@actions/app/global';
import FloatingCallContainer from '@calls/components/floating_call_container';
import {RoundedHeaderCalls} from '@calls/components/join_call_banner/rounded_header_calls';
import FreezeScreen from '@components/freeze_screen';
@@ -83,9 +84,12 @@ const Channel = ({
EphemeralStore.removeSwitchingToChannel(channelId);
}, 500);
storeLastViewedChannelIdAndServer(channelId);
return () => {
cancelAnimationFrame(raf);
clearTimeout(t);
removeLastViewedChannelIdAndServer();
EphemeralStore.removeSwitchingToChannel(channelId);
};
}, [channelId]);

View File

@@ -6,6 +6,7 @@ import React, {useCallback, useEffect, useRef, useState} from 'react';
import {type LayoutChangeEvent, StyleSheet, View} from 'react-native';
import {type Edge, SafeAreaView} from 'react-native-safe-area-context';
import {storeLastViewedThreadIdAndServer, removeLastViewedThreadIdAndServer} from '@actions/app/global';
import FloatingCallContainer from '@calls/components/floating_call_container';
import {RoundedHeaderCalls} from '@calls/components/join_call_banner/rounded_header_calls';
import FreezeScreen from '@components/freeze_screen';
@@ -18,6 +19,7 @@ import useDidUpdate from '@hooks/did_update';
import {useKeyboardTrackingPaused} from '@hooks/keyboard_tracking';
import {popTopScreen, setButtons} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import NavigationStore from '@store/navigation_store';
import ThreadPostList from './thread_post_list';
@@ -80,7 +82,17 @@ const Thread = ({
}, [componentId, rootId, isCRTEnabled]);
useEffect(() => {
// when opened from notification, first screen in stack is HOME
// if last screen was global thread or thread opened from notification, store the last viewed thread id
const isFromGlobalOrNotification = NavigationStore.getScreensInStack()[1] === Screens.GLOBAL_THREADS || NavigationStore.getScreensInStack()[1] === Screens.HOME;
if (isCRTEnabled && isFromGlobalOrNotification) {
storeLastViewedThreadIdAndServer(rootId);
}
return () => {
if (isCRTEnabled) {
removeLastViewedThreadIdAndServer();
}
if (rootId === EphemeralStore.getCurrentThreadId()) {
EphemeralStore.setCurrentThreadId('');
}