[Gekidou DB]: Adds threads in team database table and handlers (#6090)

* Adds threads in team database table and handlers

DM/GM channels have no team ID. This makes it troublesome to paginate
threads in a team. The issue is that whenever a DM/GM thread is fetched
from pagination it will be added in all teams in that server,
potentially creating gaps in between threads for those teams.

This PR inserts a new table in the DB ThreadsInTeam which will hold
references of threads loaded in which server.
Thread lists then would have to rely on that table to show threads.


Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
Co-authored-by: Avinash Lingaloo <avinashlng1080@gmail.com>
This commit is contained in:
Kyriakos Z
2022-03-28 10:11:13 +03:00
committed by GitHub
parent 86ae1fc9cc
commit f2484297a8
19 changed files with 331 additions and 12 deletions

View File

@@ -26,5 +26,6 @@ export {default as TeamModel} from './team';
export {default as TeamSearchHistoryModel} from './team_search_history';
export {default as TermsOfServiceModel} from './terms_of_service';
export {default as ThreadModel} from './thread';
export {default as ThreadInTeamModel} from './thread_in_team';
export {default as ThreadParticipantModel} from './thread_participant';
export {default as UserModel} from './user';

View File

@@ -1,8 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Relation} from '@nozbe/watermelondb';
import {children, field, immutableRelation} from '@nozbe/watermelondb/decorators';
import {Q, Relation} from '@nozbe/watermelondb';
import {children, field, immutableRelation, lazy} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
@@ -14,6 +14,7 @@ import type SlashCommandModel from '@typings/database/models/servers/slash_comma
import type TeamChannelHistoryModel from '@typings/database/models/servers/team_channel_history';
import type TeamMembershipModel from '@typings/database/models/servers/team_membership';
import type TeamSearchHistoryModel from '@typings/database/models/servers/team_search_history';
import type ThreadModel from '@typings/database/models/servers/thread';
const {
CATEGORY,
@@ -24,6 +25,8 @@ const {
TEAM_CHANNEL_HISTORY,
TEAM_MEMBERSHIP,
TEAM_SEARCH_HISTORY,
THREADS_IN_TEAM,
THREAD,
} = MM_TABLES.SERVER;
/**
@@ -53,6 +56,9 @@ export default class TeamModel extends Model {
/** A TEAM has a 1:N relationship with TEAM_SEARCH_HISTORY. A TEAM can possess multiple search histories*/
[TEAM_SEARCH_HISTORY]: {type: 'has_many', foreignKey: 'team_id'},
/** A TEAM has a 1:N relationship with THREADS_IN_TEAM. A TEAM can possess multiple threads */
[THREADS_IN_TEAM]: {type: 'has_many', foreignKey: 'team_id'},
};
/** is_allow_open_invite : Boolean flag indicating if this team is open to the public */
@@ -102,4 +108,21 @@ export default class TeamModel extends Model {
/** teamSearchHistories : All the searches performed on this team */
@children(TEAM_SEARCH_HISTORY) teamSearchHistories!: TeamSearchHistoryModel[];
/** threads : All threads belonging to a team */
@lazy threads = this.collections.get<ThreadModel>(THREAD).query(
Q.on(THREADS_IN_TEAM, 'team_id', this.id),
);
/** threads : Threads list belonging to a team */
@lazy threadsList = this.threads.extend(
Q.where('loadedInGlobalThreads', true),
Q.sortBy('last_reply_at', Q.desc),
);
/** unreadThreadsList : Unread threads list belonging to a team */
@lazy unreadThreadsList = this.threads.extend(
Q.where('unread_replies', Q.gt(0)),
Q.sortBy('last_reply_at', Q.desc),
);
}

View File

@@ -8,9 +8,10 @@ import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
import type PostModel from '@typings/database/models/servers/post';
import type ThreadInTeamModel from '@typings/database/models/servers/thread_in_team';
import type ThreadParticipantModel from '@typings/database/models/servers/thread_participant';
const {POST, THREAD, THREAD_PARTICIPANT} = MM_TABLES.SERVER;
const {POST, THREAD, THREAD_PARTICIPANT, THREADS_IN_TEAM} = MM_TABLES.SERVER;
/**
* The Thread model contains thread information of a post.
@@ -27,6 +28,9 @@ export default class ThreadModel extends Model {
/** A THREAD can have multiple THREAD_PARTICIPANT. (relationship is 1:N)*/
[THREAD_PARTICIPANT]: {type: 'has_many', foreignKey: 'thread_id'},
/** A THREAD can have multiple THREADS_IN_TEAM. (relationship is 1:N)*/
[THREADS_IN_TEAM]: {type: 'has_many', foreignKey: 'team_id'},
};
/** last_reply_at : The timestamp of when user last replied to the thread. */
@@ -53,11 +57,15 @@ export default class ThreadModel extends Model {
/** participants : All the participants associated with this Thread */
@children(THREAD_PARTICIPANT) participants!: Query<ThreadParticipantModel>;
/** threadsInTeam : All the threadsInTeam associated with this Thread */
@children(THREADS_IN_TEAM) threadsInTeam!: Query<ThreadInTeamModel>;
/** post : The root post of this thread */
@immutableRelation(POST, 'id') post!: Relation<PostModel>;
async destroyPermanently() {
await this.participants.destroyAllPermanently();
await this.threadsInTeam.destroyAllPermanently();
super.destroyPermanently();
}
}

View File

@@ -0,0 +1,42 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
import type TeamModel from '@typings/database/models/servers/team';
import type ThreadModel from '@typings/database/models/servers/thread';
const {TEAM, THREAD, THREADS_IN_TEAM} = MM_TABLES.SERVER;
/**
* ThreadInTeam model helps us to combine adjacent threads together without leaving
* gaps in between for an efficient user reading experience for threads.
*/
export default class ThreadInTeamModel extends Model {
/** table (name) : ThreadsInTeam */
static table = THREADS_IN_TEAM;
/** associations : Describes every relationship to this table. */
static associations: Associations = {
/** A TEAM can have many THREADS_IN_TEAM. (relationship is N:1)*/
[TEAM]: {type: 'belongs_to', key: 'team_id'},
/** A THREAD can have many THREADS_IN_TEAM. (relationship is N:1)*/
[THREAD]: {type: 'belongs_to', key: 'team_id'},
};
/** thread_id: Associated thread identifier */
@field('thread_id') threadId!: string;
/** team_id: Associated team identifier */
@field('team_id') teamId!: string;
@immutableRelation(THREAD, 'thread_id') thread!: Relation<ThreadModel>;
@immutableRelation(TEAM, 'team_id') team!: Relation<TeamModel>;
}