forked from Ivasoft/mattermost-mobile
Graph QL POC (#6024)
* First approach * Lint * Fixes and adding monitoring console statements (to be removed later) * Add pagination and apply graphQL also to login * Get all entry points to use the same GQL call * Unify gql handling * Use graphQL on websocket reconnect * Handle latest changes regarding categories * Use graphQL to properly fetch channel members on other servers * Remove logs and fetch unreads from other teams * Minor fixes * Final fixes * Address feedback, minor refactoring, and fixes around the refactor * Fix custom status duration types * Add missing fields and some reordering * Add timeout to fetch posts for unread channels
This commit is contained in:
committed by
GitHub
parent
6c5043d598
commit
bae5477b35
16
app/client/graphQL/constants.ts
Normal file
16
app/client/graphQL/constants.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export const QUERY_ENTRY = 'gql_m_entry';
|
||||
export const QUERY_CHANNELS = 'gql_m_channels';
|
||||
export const QUERY_CHANNELS_NEXT = 'gql_m_channels_next';
|
||||
export const QUERY_ALL_CHANNELS = 'gql_m_all_channels';
|
||||
export const QUERY_ALL_CHANNELS_NEXT = 'gql_m_all_channels_next';
|
||||
|
||||
export default {
|
||||
QUERY_ENTRY,
|
||||
QUERY_CHANNELS,
|
||||
QUERY_CHANNELS_NEXT,
|
||||
QUERY_ALL_CHANNELS,
|
||||
QUERY_ALL_CHANNELS_NEXT,
|
||||
};
|
||||
371
app/client/graphQL/entry.ts
Normal file
371
app/client/graphQL/entry.ts
Normal file
@@ -0,0 +1,371 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import {MEMBERS_PER_PAGE} from '@constants/graphql';
|
||||
import NetworkManager from '@managers/network_manager';
|
||||
|
||||
import {Client} from '../rest';
|
||||
|
||||
import QueryNames from './constants';
|
||||
|
||||
const doGQLQuery = async (serverUrl: string, query: string, variables: {[name: string]: any}, operationName: string) => {
|
||||
let client: Client;
|
||||
try {
|
||||
client = NetworkManager.getClient(serverUrl);
|
||||
} catch (error) {
|
||||
return {error};
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await client.doFetch('/api/v5/graphql', {method: 'post', body: JSON.stringify({query, variables, operationName})}) as GQLResponse;
|
||||
return response;
|
||||
} catch (error) {
|
||||
return {error};
|
||||
}
|
||||
};
|
||||
|
||||
export const gqlEntry = async (serverUrl: string) => {
|
||||
return doGQLQuery(serverUrl, entryQuery, {}, QueryNames.QUERY_ENTRY);
|
||||
};
|
||||
|
||||
export const gqlEntryChannels = async (serverUrl: string, teamId: string) => {
|
||||
const variables = {
|
||||
teamId,
|
||||
exclude: false,
|
||||
perPage: MEMBERS_PER_PAGE,
|
||||
};
|
||||
const response = await doGQLQuery(serverUrl, channelsQuery, variables, QueryNames.QUERY_CHANNELS);
|
||||
if ('error' in response || response.errors) {
|
||||
return response;
|
||||
}
|
||||
|
||||
let members = response.data.channelMembers;
|
||||
|
||||
while (members?.length === MEMBERS_PER_PAGE) {
|
||||
let pageResponse;
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
pageResponse = await gqlEntryChannelsNextPage(serverUrl, teamId, members[members.length - 1].cursor!, false);
|
||||
} catch {
|
||||
break;
|
||||
}
|
||||
|
||||
if ('error' in pageResponse) {
|
||||
break;
|
||||
}
|
||||
|
||||
members = pageResponse.data.channelMembers!;
|
||||
response.data.channelMembers?.push(...members);
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
const gqlEntryChannelsNextPage = async (serverUrl: string, teamId: string, cursor: string, exclude: boolean) => {
|
||||
const variables = {
|
||||
teamId,
|
||||
exclude,
|
||||
perPage: MEMBERS_PER_PAGE,
|
||||
cursor,
|
||||
};
|
||||
return doGQLQuery(serverUrl, nextPageChannelsQuery, variables, QueryNames.QUERY_CHANNELS_NEXT);
|
||||
};
|
||||
|
||||
export const gqlOtherChannels = async (serverUrl: string, teamId: string) => {
|
||||
const variables = {
|
||||
teamId,
|
||||
exclude: true,
|
||||
perPage: MEMBERS_PER_PAGE,
|
||||
};
|
||||
const response = await doGQLQuery(serverUrl, channelsQuery, variables, QueryNames.QUERY_CHANNELS);
|
||||
if ('error' in response || response.errors) {
|
||||
return response;
|
||||
}
|
||||
|
||||
let members = response.data.channelMembers;
|
||||
|
||||
while (members?.length === MEMBERS_PER_PAGE) {
|
||||
let pageResponse;
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
pageResponse = await gqlEntryChannelsNextPage(serverUrl, teamId, members[members.length - 1].cursor!, true);
|
||||
} catch {
|
||||
break;
|
||||
}
|
||||
|
||||
if ('error' in pageResponse || 'errors' in pageResponse) {
|
||||
break;
|
||||
}
|
||||
|
||||
members = pageResponse.data.channelMembers!;
|
||||
response.data.channelMembers?.push(...members);
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
export const gqlAllChannels = async (serverUrl: string) => {
|
||||
const variables = {
|
||||
perPage: MEMBERS_PER_PAGE,
|
||||
};
|
||||
const response = await doGQLQuery(serverUrl, allChannelsQuery, variables, QueryNames.QUERY_ALL_CHANNELS);
|
||||
if ('error' in response || response.errors) {
|
||||
return response;
|
||||
}
|
||||
|
||||
let members = response.data.channelMembers;
|
||||
|
||||
while (members?.length === MEMBERS_PER_PAGE) {
|
||||
let pageResponse;
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
pageResponse = await gqlAllChannelsNextPage(serverUrl, members[members.length - 1].cursor!);
|
||||
} catch {
|
||||
break;
|
||||
}
|
||||
|
||||
if ('error' in pageResponse || 'errors' in pageResponse) {
|
||||
break;
|
||||
}
|
||||
|
||||
members = pageResponse.data.channelMembers!;
|
||||
response.data.channelMembers?.push(...members);
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
const gqlAllChannelsNextPage = async (serverUrl: string, cursor: string) => {
|
||||
const variables = {
|
||||
perPage: MEMBERS_PER_PAGE,
|
||||
cursor,
|
||||
};
|
||||
return doGQLQuery(serverUrl, nextPageAllChannelsQuery, variables, QueryNames.QUERY_ALL_CHANNELS_NEXT);
|
||||
};
|
||||
|
||||
const entryQuery = `
|
||||
query ${QueryNames.QUERY_ENTRY} {
|
||||
config
|
||||
license
|
||||
user(id:"me") {
|
||||
id
|
||||
createAt
|
||||
updateAt
|
||||
deleteAt
|
||||
username
|
||||
authService
|
||||
email
|
||||
emailVerified
|
||||
nickname
|
||||
firstName
|
||||
lastName
|
||||
position
|
||||
roles {
|
||||
id
|
||||
name
|
||||
permissions
|
||||
}
|
||||
locale
|
||||
notifyProps
|
||||
props
|
||||
timezone
|
||||
isBot
|
||||
lastPictureUpdate
|
||||
remoteId
|
||||
status {
|
||||
status
|
||||
}
|
||||
botDescription
|
||||
botLastIconUpdate
|
||||
preferences{
|
||||
category
|
||||
name
|
||||
value
|
||||
userId
|
||||
}
|
||||
sessions {
|
||||
createAt
|
||||
expiresAt
|
||||
}
|
||||
}
|
||||
teamMembers(userId:"me") {
|
||||
deleteAt
|
||||
roles {
|
||||
id
|
||||
name
|
||||
permissions
|
||||
}
|
||||
team {
|
||||
id
|
||||
description
|
||||
displayName
|
||||
name
|
||||
type
|
||||
allowedDomains
|
||||
lastTeamIconUpdate
|
||||
groupConstrained
|
||||
allowOpenInvite
|
||||
createAt
|
||||
updateAt
|
||||
deleteAt
|
||||
schemeId
|
||||
policyId
|
||||
cloudLimitsArchived
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const channelsQuery = `
|
||||
query ${QueryNames.QUERY_CHANNELS}($teamId: String!, $perPage: Int!, $exclude: Boolean!) {
|
||||
channelMembers(userId:"me", first:$perPage, teamId:$teamId, excludeTeam:$exclude) {
|
||||
cursor
|
||||
msgCount
|
||||
msgCountRoot
|
||||
mentionCount
|
||||
lastViewedAt
|
||||
notifyProps
|
||||
roles {
|
||||
id
|
||||
name
|
||||
permissions
|
||||
}
|
||||
channel {
|
||||
id
|
||||
header
|
||||
purpose
|
||||
type
|
||||
createAt
|
||||
creatorId
|
||||
deleteAt
|
||||
displayName
|
||||
prettyDisplayName
|
||||
groupConstrained
|
||||
name
|
||||
shared
|
||||
lastPostAt
|
||||
totalMsgCount
|
||||
totalMsgCountRoot
|
||||
lastRootPostAt
|
||||
team {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
sidebarCategories(userId:"me", teamId:$teamId, excludeTeam:$exclude) {
|
||||
displayName
|
||||
id
|
||||
sorting
|
||||
type
|
||||
muted
|
||||
collapsed
|
||||
channelIds
|
||||
teamId
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const nextPageChannelsQuery = `
|
||||
query ${QueryNames.QUERY_CHANNELS_NEXT}($teamId: String!, $perPage: Int!, $exclude: Boolean!, $cursor: String!) {
|
||||
channelMembers(userId:"me", first:$perPage, after:$cursor, teamId:$teamId, excludeTeam:$exclude) {
|
||||
cursor
|
||||
msgCount
|
||||
msgCountRoot
|
||||
mentionCount
|
||||
lastViewedAt
|
||||
notifyProps
|
||||
roles {
|
||||
id
|
||||
name
|
||||
permissions
|
||||
}
|
||||
channel {
|
||||
id
|
||||
header
|
||||
purpose
|
||||
type
|
||||
createAt
|
||||
creatorId
|
||||
deleteAt
|
||||
displayName
|
||||
prettyDisplayName
|
||||
groupConstrained
|
||||
name
|
||||
shared
|
||||
lastPostAt
|
||||
totalMsgCount
|
||||
totalMsgCountRoot
|
||||
lastRootPostAt
|
||||
team {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const allChannelsQuery = `
|
||||
query ${QueryNames.QUERY_ALL_CHANNELS}($perPage: Int!){
|
||||
channelMembers(userId:"me", first:$perPage) {
|
||||
cursor
|
||||
msgCount
|
||||
msgCountRoot
|
||||
mentionCount
|
||||
lastViewedAt
|
||||
notifyProps
|
||||
channel {
|
||||
id
|
||||
header
|
||||
purpose
|
||||
type
|
||||
createAt
|
||||
creatorId
|
||||
deleteAt
|
||||
displayName
|
||||
prettyDisplayName
|
||||
groupConstrained
|
||||
name
|
||||
shared
|
||||
lastPostAt
|
||||
totalMsgCount
|
||||
totalMsgCountRoot
|
||||
lastRootPostAt
|
||||
team {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const nextPageAllChannelsQuery = `
|
||||
query ${QueryNames.QUERY_ALL_CHANNELS_NEXT}($perPage: Int!, $cursor: String!) {
|
||||
channelMembers(userId:"me", first:$perPage, after:$cursor) {
|
||||
cursor
|
||||
msgCount
|
||||
msgCountRoot
|
||||
mentionCount
|
||||
lastViewedAt
|
||||
notifyProps
|
||||
channel {
|
||||
id
|
||||
header
|
||||
purpose
|
||||
type
|
||||
createAt
|
||||
creatorId
|
||||
deleteAt
|
||||
displayName
|
||||
prettyDisplayName
|
||||
groupConstrained
|
||||
name
|
||||
shared
|
||||
lastPostAt
|
||||
totalMsgCount
|
||||
totalMsgCountRoot
|
||||
lastRootPostAt
|
||||
team {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
Reference in New Issue
Block a user