Files
mattermost-mobile/app/database/subscription/unreads.ts
Elias Nahum 75ed884e65 Add column last_fetched_at to MyChannel & Thread tables and the migration (#6433)
* Add column last_fetched_at to MyChannel & Thread tables and the migration

* Fix schema tests

* Handle lastFetchAt, retrieve threads on init and properly observe thread unreads (#6436)

* [Gekidou] Set lastFetchAt when fetching posts for a channel (#6437)

* Set lastFetchAt when fetching posts for a channel

* When resetting _preparedState set always to null

* Revert changes in WS

* Handle and set lastFetchedAt for MyChannel in iOS push notification

* feedback review

* iOS fallback to last post createAt if no lastFetchAt set

* Handle lastFetchAt on Android push notifications

* create storePostsForChannel local action

* Fix iOS fallback to last post create_at

Co-authored-by: Daniel Espino García <larkox@gmail.com>
2022-06-29 13:28:50 -04:00

123 lines
4.8 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
import {map as map$, Subscription} from 'rxjs';
import {combineLatestWith} from 'rxjs/operators';
import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
import {observeAllMyChannelNotifyProps} from '@queries/servers/channel';
import {queryMyTeams} from '@queries/servers/team';
import {getIsCRTEnabled, observeThreadMentionCount, queryThreads, observeUnreadsAndMentionsInTeam} from '@queries/servers/thread';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
const {SERVER: {CHANNEL, MY_CHANNEL}} = MM_TABLES;
export type UnreadObserverArgs = {
myChannels: MyChannelModel[];
settings?: Record<string, Partial<ChannelNotifyProps>>;
threadUnreads?: boolean;
threadMentionCount: number;
}
type ServerUnreadObserver = {
(serverUrl: string, {myChannels, settings, threadMentionCount, threadUnreads}: UnreadObserverArgs): void;
}
type UnreadObserver = {
({myChannels, settings, threadMentionCount, threadUnreads}: UnreadObserverArgs): void;
}
export const subscribeServerUnreadAndMentions = (serverUrl: string, observer: UnreadObserver) => {
const server = DatabaseManager.serverDatabases[serverUrl];
let subscription: Subscription|undefined;
if (server?.database) {
subscription = server.database.get<MyChannelModel>(MY_CHANNEL).
query(Q.on(CHANNEL, Q.where('delete_at', Q.eq(0)))).
observeWithColumns(['is_unread', 'mentions_count']).
pipe(
combineLatestWith(observeAllMyChannelNotifyProps(server.database)),
combineLatestWith(observeUnreadsAndMentionsInTeam(server.database, undefined, false)),
map$(([[myChannels, settings], {unreads, mentions}]) => ({myChannels, settings, threadUnreads: unreads, threadMentionCount: mentions})),
).
subscribe(observer);
}
return subscription;
};
export const subscribeMentionsByServer = (serverUrl: string, observer: ServerUnreadObserver) => {
const server = DatabaseManager.serverDatabases[serverUrl];
let subscription: Subscription|undefined;
if (server?.database) {
subscription = server.database.
get<MyChannelModel>(MY_CHANNEL).
query(Q.on(CHANNEL, Q.where('delete_at', Q.eq(0)))).
observeWithColumns(['mentions_count']).
pipe(
combineLatestWith(observeThreadMentionCount(server.database, undefined, false)),
map$(([myChannels, threadMentionCount]) => ({myChannels, threadMentionCount})),
).
subscribe(observer.bind(undefined, serverUrl));
}
return subscription;
};
export const subscribeUnreadAndMentionsByServer = (serverUrl: string, observer: ServerUnreadObserver) => {
const server = DatabaseManager.serverDatabases[serverUrl];
let subscription: Subscription|undefined;
if (server?.database) {
subscription = server.database.get<MyChannelModel>(MY_CHANNEL).
query(Q.on(CHANNEL, Q.where('delete_at', Q.eq(0)))).
observeWithColumns(['mentions_count', 'is_unread']).
pipe(
combineLatestWith(observeAllMyChannelNotifyProps(server.database)),
combineLatestWith(observeUnreadsAndMentionsInTeam(server.database, undefined, false)),
map$(([[myChannels, settings], {unreads, mentions}]) => ({myChannels, settings, threadUnreads: unreads, threadMentionCount: mentions})),
).
subscribe(observer.bind(undefined, serverUrl));
}
return subscription;
};
export const getTotalMentionsForServer = async (serverUrl: string) => {
const server = DatabaseManager.serverDatabases[serverUrl];
let count = 0;
if (server?.database) {
const {database} = server;
const myChannels = await database.get<MyChannelModel>(MY_CHANNEL).
query(
Q.on(CHANNEL, Q.where('delete_at', Q.eq(0))),
Q.where('mentions_count', Q.gt(0)),
).fetch();
for (const mc of myChannels) {
count += mc.mentionsCount;
}
const isCRTEnabled = await getIsCRTEnabled(database);
if (isCRTEnabled) {
let includeDmGm = true;
const myTeamIds = await queryMyTeams(database).fetchIds();
for await (const teamId of myTeamIds) {
const threads = await queryThreads(database, teamId, false, includeDmGm).extend(
Q.where('unread_mentions', Q.gt(0)),
).fetch();
includeDmGm = false;
for (const t of threads) {
count += t.unreadMentions;
}
}
}
}
return count;
};