forked from Ivasoft/mattermost-mobile
[Gekidou CRT] thread mention counts (#6126)
* Sets values on my_channel according to CRT * Team counts with regard to CRT * Fixes myChannel.is_unread with regard to CRT * Include DM/GMs for thread counts on demand * Incorporate thread mention counts in server/channel * Channel updates in regard to CRT
This commit is contained in:
@@ -186,7 +186,7 @@ export async function markTeamThreadsAsRead(serverUrl: string, teamId: string, p
|
||||
}
|
||||
try {
|
||||
const {database} = operator;
|
||||
const threads = await queryThreadsInTeam(database, teamId, true).fetch();
|
||||
const threads = await queryThreadsInTeam(database, teamId, true, true, true).fetch();
|
||||
const models = threads.map((thread) => thread.prepareUpdate((record) => {
|
||||
record.unreadMentions = 0;
|
||||
record.unreadReplies = 0;
|
||||
|
||||
@@ -226,6 +226,8 @@ export async function fetchPostsForChannel(serverUrl: string, channelId: string,
|
||||
}
|
||||
|
||||
if (!fetchOnly) {
|
||||
const isCRTEnabled = await getIsCRTEnabled(operator.database);
|
||||
|
||||
const models = [];
|
||||
const postModels = await operator.handlePosts({
|
||||
actionType,
|
||||
@@ -243,14 +245,18 @@ export async function fetchPostsForChannel(serverUrl: string, channelId: string,
|
||||
|
||||
let lastPostAt = 0;
|
||||
for (const post of data.posts) {
|
||||
lastPostAt = post.create_at > lastPostAt ? post.create_at : lastPostAt;
|
||||
}
|
||||
const {member: memberModel} = await updateLastPostAt(serverUrl, channelId, lastPostAt, true);
|
||||
if (memberModel) {
|
||||
models.push(memberModel);
|
||||
if (!isCRTEnabled || post.root_id) {
|
||||
lastPostAt = post.create_at > lastPostAt ? post.create_at : lastPostAt;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastPostAt) {
|
||||
const {member: memberModel} = await updateLastPostAt(serverUrl, channelId, lastPostAt, true);
|
||||
if (memberModel) {
|
||||
models.push(memberModel);
|
||||
}
|
||||
}
|
||||
|
||||
const isCRTEnabled = await getIsCRTEnabled(operator.database);
|
||||
if (isCRTEnabled) {
|
||||
const threadModels = await prepareThreadsFromReceivedPosts(operator, data.posts);
|
||||
if (threadModels?.length) {
|
||||
@@ -841,8 +847,18 @@ export const markPostAsUnread = async (serverUrl: string, postId: string) => {
|
||||
client.getChannelMember(channelId, userId),
|
||||
]);
|
||||
if (channel && channelMember) {
|
||||
const messageCount = channel.total_msg_count - channelMember.msg_count;
|
||||
const mentionCount = channelMember.mention_count;
|
||||
const isCRTEnabled = await getIsCRTEnabled(database);
|
||||
let totalMessages = channel.total_msg_count;
|
||||
let messages = channelMember.msg_count;
|
||||
let mentionCount = channelMember.mention_count;
|
||||
|
||||
if (isCRTEnabled) {
|
||||
totalMessages = channel.total_msg_count_root!;
|
||||
messages = channelMember.msg_count_root!;
|
||||
mentionCount = channelMember.mention_count_root!;
|
||||
}
|
||||
|
||||
const messageCount = totalMessages - messages;
|
||||
await markChannelAsUnread(serverUrl, channelId, messageCount, mentionCount, post.createAt);
|
||||
return {
|
||||
post,
|
||||
|
||||
@@ -149,7 +149,7 @@ export async function handleNewPostEvent(serverUrl: string, msg: WebSocketMessag
|
||||
if (viewedAt) {
|
||||
models.push(viewedAt);
|
||||
}
|
||||
} else {
|
||||
} else if (!isCRTEnabled || !post.root_id) {
|
||||
const hasMentions = msg.data.mentions?.includes(currentUserId);
|
||||
preparedMyChannelHack(myChannel);
|
||||
const {member: unreadAt} = await markChannelAsUnread(
|
||||
@@ -246,18 +246,36 @@ export async function handlePostDeleted(serverUrl: string, msg: WebSocketMessage
|
||||
|
||||
export async function handlePostUnread(serverUrl: string, msg: WebSocketMessage) {
|
||||
const {channel_id: channelId, team_id: teamId} = msg.broadcast;
|
||||
const {mention_count: mentionCount, msg_count: msgCount, last_viewed_at: lastViewedAt} = msg.data;
|
||||
const {
|
||||
mention_count: mentionCount,
|
||||
mention_count_root: mentionCountRoot,
|
||||
msg_count: msgCount,
|
||||
msg_count_root: msgCountRoot,
|
||||
last_viewed_at: lastViewedAt,
|
||||
} = msg.data;
|
||||
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
return;
|
||||
}
|
||||
const [myChannel, isCRTEnabled] = await Promise.all([
|
||||
getMyChannel(database, channelId),
|
||||
getIsCRTEnabled(database),
|
||||
]);
|
||||
|
||||
let messages = msgCount;
|
||||
let mentions = mentionCount;
|
||||
if (isCRTEnabled) {
|
||||
messages = msgCountRoot;
|
||||
mentions = mentionCountRoot;
|
||||
}
|
||||
|
||||
const myChannel = await getMyChannel(database, channelId);
|
||||
if (!myChannel?.manuallyUnread) {
|
||||
const {channels} = await fetchMyChannel(serverUrl, teamId, channelId, true);
|
||||
const channel = channels?.[0];
|
||||
const postNumber = channel?.total_msg_count;
|
||||
const delta = postNumber ? postNumber - msgCount : msgCount;
|
||||
markChannelAsUnread(serverUrl, channelId, delta, mentionCount, lastViewedAt);
|
||||
const postNumber = isCRTEnabled ? channel?.total_msg_count_root : channel?.total_msg_count;
|
||||
const delta = postNumber ? postNumber - messages : messages;
|
||||
|
||||
markChannelAsUnread(serverUrl, channelId, delta, mentions, lastViewedAt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {switchMap} from 'rxjs/operators';
|
||||
|
||||
import {queryMyChannelsByTeam} from '@queries/servers/channel';
|
||||
import {observeCurrentTeamId} from '@queries/servers/system';
|
||||
import {observeMentionCount} from '@queries/servers/team';
|
||||
|
||||
import TeamItem from './team_item';
|
||||
|
||||
@@ -20,10 +21,6 @@ type WithTeamsArgs = WithDatabaseArgs & {
|
||||
|
||||
const enhance = withObservables(['myTeam'], ({myTeam, database}: WithTeamsArgs) => {
|
||||
const myChannels = queryMyChannelsByTeam(database, myTeam.id).observeWithColumns(['mentions_count', 'is_unread']);
|
||||
const mentionCount = myChannels.pipe(
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
switchMap((val) => of$(val.reduce((acc, v) => acc + v.mentionsCount, 0))),
|
||||
);
|
||||
const hasUnreads = myChannels.pipe(
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
switchMap((val) => of$(val.reduce((acc, v) => acc || v.isUnread, false))),
|
||||
@@ -32,7 +29,7 @@ const enhance = withObservables(['myTeam'], ({myTeam, database}: WithTeamsArgs)
|
||||
return {
|
||||
currentTeamId: observeCurrentTeamId(database),
|
||||
team: myTeam.team.observe(),
|
||||
mentionCount,
|
||||
mentionCount: observeMentionCount(database, myTeam.id, false),
|
||||
hasUnreads,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
transformMyChannelSettingsRecord,
|
||||
} from '@database/operator/server_data_operator/transformers/channel';
|
||||
import {getUniqueRawsBy} from '@database/operator/utils/general';
|
||||
import {getIsCRTEnabled} from '@queries/servers/thread';
|
||||
|
||||
import type {HandleChannelArgs, HandleChannelInfoArgs, HandleChannelMembershipArgs, HandleMyChannelArgs, HandleMyChannelSettingsArgs} from '@typings/database/database';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
@@ -156,14 +157,19 @@ const ChannelHandler = (superclass: any) => class extends superclass {
|
||||
return [];
|
||||
}
|
||||
|
||||
const isCRTEnabled = await getIsCRTEnabled(this.database);
|
||||
|
||||
const channelMap = channels.reduce((result: Record<string, Channel>, channel) => {
|
||||
result[channel.id] = channel;
|
||||
return result;
|
||||
}, {});
|
||||
|
||||
for (const my of myChannels) {
|
||||
const channel = channelMap[my.channel_id];
|
||||
if (channel) {
|
||||
const msgCount = Math.max(0, channel.total_msg_count - my.msg_count);
|
||||
const total = isCRTEnabled ? channel.total_msg_count_root! : channel.total_msg_count;
|
||||
const myMsgCount = isCRTEnabled ? my.msg_count_root! : my.msg_count;
|
||||
const msgCount = Math.max(0, total - myMsgCount);
|
||||
my.msg_count = msgCount;
|
||||
my.is_unread = msgCount > 0;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
import {prepareBaseRecord} from '@database/operator/server_data_operator/transformers/index';
|
||||
import {extractChannelDisplayName} from '@helpers/database';
|
||||
import {getIsCRTEnabled} from '@queries/servers/thread';
|
||||
import {OperationType} from '@typings/database/enums';
|
||||
|
||||
import type {TransformerArgs} from '@typings/database/database';
|
||||
@@ -120,18 +121,20 @@ export const transformChannelInfoRecord = ({action, database, value}: Transforme
|
||||
* @param {RecordPair} operator.value
|
||||
* @returns {Promise<MyChannelModel>}
|
||||
*/
|
||||
export const transformMyChannelRecord = ({action, database, value}: TransformerArgs): Promise<MyChannelModel> => {
|
||||
export const transformMyChannelRecord = async ({action, database, value}: TransformerArgs): Promise<MyChannelModel> => {
|
||||
const raw = value.raw as ChannelMembership;
|
||||
const record = value.record as MyChannelModel;
|
||||
const isCreateAction = action === OperationType.CREATE;
|
||||
|
||||
const isCRTEnabled = await getIsCRTEnabled(database);
|
||||
|
||||
const fieldsMapper = (myChannel: MyChannelModel) => {
|
||||
myChannel._raw.id = isCreateAction ? (raw.channel_id || myChannel.id) : record.id;
|
||||
myChannel.roles = raw.roles;
|
||||
myChannel.messageCount = raw.msg_count;
|
||||
myChannel.messageCount = isCRTEnabled ? raw.msg_count_root! : raw.msg_count;
|
||||
myChannel.isUnread = Boolean(raw.is_unread);
|
||||
myChannel.mentionsCount = raw.mention_count;
|
||||
myChannel.lastPostAt = raw.last_post_at || 0;
|
||||
myChannel.mentionsCount = isCRTEnabled ? raw.mention_count_root! : raw.mention_count;
|
||||
myChannel.lastPostAt = (isCRTEnabled ? (raw.last_root_post_at || raw.last_post_at) : raw.last_post_at) || 0;
|
||||
myChannel.lastViewedAt = raw.last_viewed_at;
|
||||
myChannel.viewedAt = record?.viewedAt || 0;
|
||||
};
|
||||
|
||||
@@ -2,16 +2,23 @@
|
||||
// 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 {observeThreadMentionCount} from '@queries/servers/thread';
|
||||
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type {Subscription} from 'rxjs';
|
||||
|
||||
const {SERVER: {CHANNEL, MY_CHANNEL}} = MM_TABLES;
|
||||
|
||||
export const subscribeServerUnreadAndMentions = (serverUrl: string, observer: (myChannels: MyChannelModel[]) => void) => {
|
||||
type ObserverArgs = {
|
||||
myChannels: MyChannelModel[];
|
||||
threadMentionCount: number;
|
||||
}
|
||||
|
||||
export const subscribeServerUnreadAndMentions = (serverUrl: string, observer: ({myChannels, threadMentionCount}: ObserverArgs) => void) => {
|
||||
const server = DatabaseManager.serverDatabases[serverUrl];
|
||||
let subscription: Subscription|undefined;
|
||||
|
||||
@@ -19,34 +26,47 @@ export const subscribeServerUnreadAndMentions = (serverUrl: string, observer: (m
|
||||
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(observeThreadMentionCount(server.database, undefined, false)),
|
||||
map$(([myChannels, threadMentionCount]) => ({myChannels, threadMentionCount})),
|
||||
).
|
||||
subscribe(observer);
|
||||
}
|
||||
|
||||
return subscription;
|
||||
};
|
||||
|
||||
export const subscribeMentionsByServer = (serverUrl: string, observer: (serverUrl: string, myChannels: MyChannelModel[]) => void) => {
|
||||
export const subscribeMentionsByServer = (serverUrl: string, observer: (serverUrl: string, {myChannels, threadMentionCount}: ObserverArgs) => void) => {
|
||||
const server = DatabaseManager.serverDatabases[serverUrl];
|
||||
let subscription: Subscription|undefined;
|
||||
|
||||
if (server?.database) {
|
||||
subscription = server.database.
|
||||
get(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: (serverUrl: string, myChannels: MyChannelModel[]) => void) => {
|
||||
export const subscribeUnreadAndMentionsByServer = (serverUrl: string, observer: (serverUrl: string, {myChannels, threadMentionCount}: ObserverArgs) => void) => {
|
||||
const server = DatabaseManager.serverDatabases[serverUrl];
|
||||
let subscription: Subscription|undefined;
|
||||
|
||||
if (server?.database) {
|
||||
subscription = server.database.
|
||||
get(MY_CHANNEL).
|
||||
subscription = server.database.get<MyChannelModel>(MY_CHANNEL).
|
||||
query(Q.on(CHANNEL, Q.where('delete_at', Q.eq(0)))).
|
||||
observeWithColumns(['mentions_count', 'has_unreads']).
|
||||
observeWithColumns(['mentions_count', 'is_unread']).
|
||||
pipe(
|
||||
combineLatestWith(observeThreadMentionCount(server.database, undefined, false)),
|
||||
map$(([myChannels, threadMentionCount]) => ({myChannels, threadMentionCount})),
|
||||
).
|
||||
subscribe(observer.bind(undefined, serverUrl));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Database, Model, Q, Query, Relation} from '@nozbe/watermelondb';
|
||||
import {of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
import {of as of$, Observable} from 'rxjs';
|
||||
import {switchMap, distinctUntilChanged} from 'rxjs/operators';
|
||||
|
||||
import {General, Permissions} from '@constants';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
@@ -372,3 +372,26 @@ export const queryMyChannelSettingsByIds = (database: Database, ids: string[]) =
|
||||
export const queryChannelsByNames = (database: Database, names: string[]) => {
|
||||
return database.get<ChannelModel>(CHANNEL).query(Q.where('name', Q.oneOf(names)));
|
||||
};
|
||||
|
||||
export function observeMyChannelMentionCount(database: Database, teamId?: string, columns = ['mentions_count', 'is_unread']): Observable<number> {
|
||||
const conditions: Q.Condition[] = [
|
||||
Q.where('delete_at', Q.eq(0)),
|
||||
];
|
||||
|
||||
if (teamId) {
|
||||
conditions.push(Q.where('team_id', Q.eq(teamId)));
|
||||
}
|
||||
|
||||
return database.get<MyChannelModel>(MY_CHANNEL).query(
|
||||
Q.on(CHANNEL, Q.and(
|
||||
...conditions,
|
||||
)),
|
||||
).
|
||||
observeWithColumns(columns).
|
||||
pipe(
|
||||
switchMap((val) => of$(val.reduce((acc, v) => {
|
||||
return acc + v.mentionsCount;
|
||||
}, 0))),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Database, Model, Q, Query, Relation} from '@nozbe/watermelondb';
|
||||
import {of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
import {of as of$, map as map$, Observable} from 'rxjs';
|
||||
import {switchMap, distinctUntilChanged, combineLatestWith} from 'rxjs/operators';
|
||||
|
||||
import {Database as DatabaseConstants, Preferences} from '@constants';
|
||||
import {getPreferenceValue} from '@helpers/api/preference';
|
||||
@@ -11,9 +11,10 @@ import {selectDefaultTeam} from '@helpers/api/team';
|
||||
import {DEFAULT_LOCALE} from '@i18n';
|
||||
|
||||
import {prepareDeleteCategory} from './categories';
|
||||
import {prepareDeleteChannel, getDefaultChannelForTeam} from './channel';
|
||||
import {prepareDeleteChannel, getDefaultChannelForTeam, observeMyChannelMentionCount} from './channel';
|
||||
import {queryPreferencesByCategoryAndName} from './preference';
|
||||
import {patchTeamHistory, getConfig, getTeamHistory, observeCurrentTeamId} from './system';
|
||||
import {observeThreadMentionCount} from './thread';
|
||||
import {getCurrentUser} from './user';
|
||||
|
||||
import type ServerDataOperator from '@database/operator/server_data_operator';
|
||||
@@ -21,7 +22,12 @@ import type MyTeamModel from '@typings/database/models/servers/my_team';
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
|
||||
|
||||
const {MY_TEAM, TEAM, TEAM_CHANNEL_HISTORY, MY_CHANNEL} = DatabaseConstants.MM_TABLES.SERVER;
|
||||
const {
|
||||
MY_CHANNEL,
|
||||
MY_TEAM,
|
||||
TEAM,
|
||||
TEAM_CHANNEL_HISTORY,
|
||||
} = DatabaseConstants.MM_TABLES.SERVER;
|
||||
|
||||
export const addChannelToTeamHistory = async (operator: ServerDataOperator, teamId: string, channelId: string, prepareRecordsOnly = false) => {
|
||||
let tch: TeamChannelHistory|undefined;
|
||||
@@ -377,3 +383,14 @@ export const observeCurrentTeam = (database: Database) => {
|
||||
switchMap((id) => observeTeam(database, id)),
|
||||
);
|
||||
};
|
||||
|
||||
export function observeMentionCount(database: Database, teamId?: string, includeDmGm?: boolean): Observable<number> {
|
||||
const channelMentionCountObservable = observeMyChannelMentionCount(database, teamId);
|
||||
const threadMentionCountObservable = observeThreadMentionCount(database, teamId, includeDmGm);
|
||||
|
||||
return channelMentionCountObservable.pipe(
|
||||
combineLatestWith(threadMentionCountObservable),
|
||||
map$(([ccount, tcount]) => ccount + tcount),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Database, Q, Query} from '@nozbe/watermelondb';
|
||||
import {combineLatest, of as of$} from 'rxjs';
|
||||
import {map, switchMap} from 'rxjs/operators';
|
||||
import {combineLatest, of as of$, Observable} from 'rxjs';
|
||||
import {map, switchMap, distinctUntilChanged} from 'rxjs/operators';
|
||||
|
||||
import {Preferences} from '@constants';
|
||||
import {MM_TABLES} from '@constants/database';
|
||||
@@ -52,17 +52,24 @@ export const observeThreadById = (database: Database, threadId: string) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const observeUnreadsAndMentionsInTeam = (database: Database, teamId: string) => {
|
||||
return queryThreadsInTeam(database, teamId, true).observeWithColumns(['unread_replies', 'unread_mentions']).pipe(
|
||||
switchMap((threads) => {
|
||||
let unreads = 0;
|
||||
let mentions = 0;
|
||||
threads.forEach((thread) => {
|
||||
unreads += thread.unreadReplies;
|
||||
mentions += thread.unreadMentions;
|
||||
});
|
||||
return of$({unreads, mentions});
|
||||
}),
|
||||
export const observeUnreadsAndMentionsInTeam = (database: Database, teamId?: string, includeDmGm?: boolean): Observable<{unreads: number; mentions: number}> => {
|
||||
const observeThreads = () => queryThreads(database, teamId, true, includeDmGm).
|
||||
observeWithColumns(['unread_replies', 'unread_mentions']).
|
||||
pipe(
|
||||
switchMap((threads) => {
|
||||
let unreads = 0;
|
||||
let mentions = 0;
|
||||
for (const thread of threads) {
|
||||
unreads += thread.unreadReplies;
|
||||
mentions += thread.unreadMentions;
|
||||
}
|
||||
|
||||
return of$({unreads, mentions});
|
||||
}),
|
||||
);
|
||||
|
||||
return observeIsCRTEnabled(database).pipe(
|
||||
switchMap((hasCRT) => (hasCRT ? observeThreads() : of$({unreads: 0, mentions: 0}))),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -125,3 +132,47 @@ export const queryThreadsInTeam = (database: Database, teamId: string, onlyUnrea
|
||||
|
||||
return database.get<ThreadModel>(THREAD).query(...query);
|
||||
};
|
||||
|
||||
export function observeThreadMentionCount(database: Database, teamId?: string, includeDmGm?: boolean): Observable<number> {
|
||||
return observeUnreadsAndMentionsInTeam(database, teamId, includeDmGm).pipe(
|
||||
switchMap(({mentions}) => of$(mentions)),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
}
|
||||
|
||||
export const queryThreads = (database: Database, teamId?: string, onlyUnreads = false, includeDmGm = true): Query<ThreadModel> => {
|
||||
const query: Q.Clause[] = [
|
||||
Q.where('is_following', true),
|
||||
Q.where('reply_count', Q.gt(0)),
|
||||
];
|
||||
|
||||
// If teamId is specified, only get threads in that team
|
||||
if (teamId) {
|
||||
let condition: Q.Condition = Q.where('team_id', teamId);
|
||||
|
||||
if (includeDmGm) {
|
||||
condition = Q.or(
|
||||
Q.where('team_id', teamId),
|
||||
Q.where('team_id', ''),
|
||||
);
|
||||
}
|
||||
|
||||
query.push(
|
||||
Q.experimentalNestedJoin(POST, CHANNEL),
|
||||
Q.on(POST, Q.on(CHANNEL, condition)),
|
||||
);
|
||||
} else if (!includeDmGm) {
|
||||
// fetching all threads from all teams
|
||||
// excluding DM/GM channels
|
||||
query.push(
|
||||
Q.experimentalNestedJoin(POST, CHANNEL),
|
||||
Q.on(POST, Q.on(CHANNEL, Q.where('team_id', Q.notEq('')))),
|
||||
);
|
||||
}
|
||||
|
||||
if (onlyUnreads) {
|
||||
query.push(Q.where('unread_replies', Q.gt(0)));
|
||||
}
|
||||
|
||||
return database.get<ThreadModel>(THREAD).query(...query);
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ const OtherMentionsBadge = ({channelId}: Props) => {
|
||||
setCount(mentions);
|
||||
};
|
||||
|
||||
const unreadsSubscription = (serverUrl: string, myChannels: MyChannelModel[]) => {
|
||||
const unreadsSubscription = (serverUrl: string, {myChannels, threadMentionCount}: {myChannels: MyChannelModel[]; threadMentionCount: number}) => {
|
||||
const unreads = subscriptions.get(serverUrl);
|
||||
if (unreads) {
|
||||
let mentions = 0;
|
||||
@@ -47,7 +47,7 @@ const OtherMentionsBadge = ({channelId}: Props) => {
|
||||
}
|
||||
}
|
||||
|
||||
unreads.mentions = mentions;
|
||||
unreads.mentions = mentions + threadMentionCount;
|
||||
subscriptions.set(serverUrl, unreads);
|
||||
updateCount();
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export default function Servers() {
|
||||
setTotal({mentions, unread});
|
||||
};
|
||||
|
||||
const unreadsSubscription = (serverUrl: string, myChannels: MyChannelModel[]) => {
|
||||
const unreadsSubscription = (serverUrl: string, {myChannels, threadMentionCount}: {myChannels: MyChannelModel[]; threadMentionCount: number}) => {
|
||||
const unreads = subscriptions.get(serverUrl);
|
||||
if (unreads) {
|
||||
let mentions = 0;
|
||||
@@ -76,7 +76,7 @@ export default function Servers() {
|
||||
unread = unread || myChannel.isUnread;
|
||||
}
|
||||
|
||||
unreads.mentions = mentions;
|
||||
unreads.mentions = mentions + threadMentionCount;
|
||||
unreads.unread = unread;
|
||||
subscriptions.set(serverUrl, unreads);
|
||||
updateTotal();
|
||||
|
||||
@@ -136,13 +136,14 @@ const ServerItem = ({highlight, isActive, server, tutorialWatched}: Props) => {
|
||||
displayName = intl.formatMessage({id: 'servers.default', defaultMessage: 'Default Server'});
|
||||
}
|
||||
|
||||
const unreadsSubscription = (myChannels: MyChannelModel[]) => {
|
||||
const unreadsSubscription = ({myChannels, threadMentionCount}: {myChannels: MyChannelModel[]; threadMentionCount: number}) => {
|
||||
let mentions = 0;
|
||||
let isUnread = false;
|
||||
for (const myChannel of myChannels) {
|
||||
mentions += myChannel.mentionsCount;
|
||||
isUnread = isUnread || myChannel.isUnread;
|
||||
}
|
||||
mentions += threadMentionCount;
|
||||
|
||||
setBadge({isUnread, mentions});
|
||||
};
|
||||
|
||||
@@ -51,7 +51,7 @@ const Home = ({isFocused, theme}: Props) => {
|
||||
setTotal({mentions, unread});
|
||||
};
|
||||
|
||||
const unreadsSubscription = (serverUrl: string, myChannels: MyChannelModel[]) => {
|
||||
const unreadsSubscription = (serverUrl: string, {myChannels, threadMentionCount}: {myChannels: MyChannelModel[]; threadMentionCount: number}) => {
|
||||
const unreads = subscriptions.get(serverUrl);
|
||||
if (unreads) {
|
||||
let mentions = 0;
|
||||
@@ -61,7 +61,7 @@ const Home = ({isFocused, theme}: Props) => {
|
||||
unread = unread || myChannel.isUnread;
|
||||
}
|
||||
|
||||
unreads.mentions = mentions;
|
||||
unreads.mentions = mentions + threadMentionCount;
|
||||
unreads.unread = unread;
|
||||
subscriptions.set(serverUrl, unreads);
|
||||
updateTotal();
|
||||
|
||||
2
types/api/channels.d.ts
vendored
2
types/api/channels.d.ts
vendored
@@ -28,6 +28,7 @@ type Channel = {
|
||||
purpose: string;
|
||||
last_post_at: number;
|
||||
total_msg_count: number;
|
||||
total_msg_count_root?: number;
|
||||
extra_update_at: number;
|
||||
creator_id: string;
|
||||
scheme_id: string|null;
|
||||
@@ -60,6 +61,7 @@ type ChannelMembership = {
|
||||
mention_count_root?: number;
|
||||
notify_props: Partial<ChannelNotifyProps>;
|
||||
last_post_at?: number;
|
||||
last_root_post_at?: number;
|
||||
last_update_at: number;
|
||||
scheme_user?: boolean;
|
||||
scheme_admin?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user