forked from Ivasoft/mattermost-mobile
[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:
@@ -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';
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
42
app/database/models/server/thread_in_team.ts
Normal file
42
app/database/models/server/thread_in_team.ts
Normal 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>;
|
||||
}
|
||||
Reference in New Issue
Block a user