V1 dependencies and bump to RN 0.67.2 (#5908)
* update dependencies * eslint fixes * Upgrade to RN 67 * update other deps * Update to RN 0.67.2 * fix Android build (mmkv) * Fix crash when root message is deleted from the thread screen * Fix gif emoji playing at high speed on iOS ProMotion capable devices
This commit is contained in:
parent
62258b5d64
commit
5ea470a235
269 changed files with 10214 additions and 15000 deletions
|
|
@ -63,4 +63,4 @@ untyped-import
|
|||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.158.0
|
||||
^0.162.0
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ def jscFlavor = 'org.webkit:android-jsc-intl:+'
|
|||
/**
|
||||
* Whether to enable the Hermes VM.
|
||||
*
|
||||
* This should be set on project.ext.react and mirrored here. If it is not set
|
||||
* This should be set on project.ext.react and that value will be read here. If it is not set
|
||||
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
|
||||
* and the benefits of using Hermes will therefore be sharply reduced.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -8,13 +8,11 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
|
||||
import com.ammarahmed.mmkv.RNMMKVModule;
|
||||
|
||||
public class CustomMMKVJSIModulePackage extends ReanimatedJSIModulePackage {
|
||||
@Override
|
||||
public List<JSIModuleSpec> getJSIModules(ReactApplicationContext reactApplicationContext, JavaScriptContextHolder jsContext) {
|
||||
super.getJSIModules(reactApplicationContext, jsContext);
|
||||
reactApplicationContext.getNativeModule(RNMMKVModule.class).installLib(jsContext, reactApplicationContext.getFilesDir().getAbsolutePath() + "/mmkv");
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
|
|
|||
36
android/app/src/main/res/drawable/rn_edit_text_material.xml
Normal file
36
android/app/src/main/res/drawable/rn_edit_text_material.xml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
|
||||
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
|
||||
android:insetTop="@dimen/abc_edit_text_inset_top_material"
|
||||
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
|
||||
|
||||
<selector>
|
||||
<!--
|
||||
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
|
||||
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
|
||||
NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
|
||||
|
||||
<item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
|
||||
|
||||
For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
|
||||
-->
|
||||
<item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
|
||||
<item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
|
||||
</selector>
|
||||
|
||||
</inset>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:windowBackground">@color/splashscreen_bg</item>
|
||||
|
||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -14,14 +14,13 @@ buildscript {
|
|||
|
||||
}
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.2'
|
||||
classpath 'com.google.gms:google-services:4.2.0'
|
||||
classpath 'com.google.gms:google-services:4.3.10'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
@ -32,9 +31,9 @@ buildscript {
|
|||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
url("$rootDir/../node_modules/react-native/android")
|
||||
|
|
@ -49,6 +48,13 @@ allprojects {
|
|||
// prebuilt libv8android.so
|
||||
// url("$rootDir/../node_modules/v8-android/dist")
|
||||
}
|
||||
mavenCentral {
|
||||
// We don't want to fetch react-native from Maven Central as there are
|
||||
// older versions over there.
|
||||
content {
|
||||
excludeGroup "com.facebook.react"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url "https://www.jitpack.io"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# Default value: -Xmx1024m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs=-Xmx2048M
|
||||
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
|
||||
|
|
|
|||
|
|
@ -19,19 +19,19 @@ import {getPreferenceKey} from '@mm-redux/utils/preference_utils';
|
|||
import {isDirectChannelVisible, isGroupChannelVisible} from '@utils/channels';
|
||||
import {buildPreference} from '@utils/preferences';
|
||||
|
||||
export async function loadSidebarDirectMessagesProfiles(state: GlobalState, channels: Array<Channel>, channelMembers: Array<ChannelMembership>) {
|
||||
export async function loadSidebarDirectMessagesProfiles(state: GlobalState, channels: Channel[], channelMembers: ChannelMembership[]) {
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const usersInChannel: RelationOneToMany<Channel, UserProfile> = getUserIdsInChannels(state);
|
||||
const directChannels = Object.values(channels).filter((c) => c.type === General.DM_CHANNEL || c.type === General.GM_CHANNEL);
|
||||
const prefs: Array<PreferenceType> = [];
|
||||
const prefs: PreferenceType[] = [];
|
||||
const promises: Array<Promise<ActionResult>> = []; //only fetch profiles that we don't have and the Direct channel should be visible
|
||||
const actions = [];
|
||||
const userIds: Array<string> = [];
|
||||
const userIds: string[] = [];
|
||||
|
||||
// Prepare preferences and start fetching profiles to batch them
|
||||
directChannels.forEach((c) => {
|
||||
const profileIds = Array.from(usersInChannel[c.id] || []);
|
||||
const profilesInChannel: Array<string> = profileIds.filter((u: string) => u !== currentUserId);
|
||||
const profilesInChannel: string[] = profileIds.filter((u: string) => u !== currentUserId);
|
||||
userIds.push(...profilesInChannel);
|
||||
|
||||
switch (c.type) {
|
||||
|
|
@ -118,7 +118,7 @@ export async function fetchMyChannelMember(channelId: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export function markChannelAsUnread(state: GlobalState, teamId: string, channelId: string, mentions: Array<string>, isRoot = false): Array<GenericAction> {
|
||||
export function markChannelAsUnread(state: GlobalState, teamId: string, channelId: string, mentions: string[], isRoot = false): GenericAction[] {
|
||||
const {myMembers} = state.entities.channels;
|
||||
const {currentUserId} = state.entities.users;
|
||||
|
||||
|
|
@ -214,8 +214,8 @@ export async function makeGroupMessageVisibleIfNecessary(state: GlobalState, cha
|
|||
}
|
||||
}
|
||||
|
||||
export async function fetchChannelAndMyMember(channelId: string): Promise<Array<GenericAction>> {
|
||||
const actions: Array<GenericAction> = [];
|
||||
export async function fetchChannelAndMyMember(channelId: string): Promise<GenericAction[]> {
|
||||
const actions: GenericAction[] = [];
|
||||
|
||||
try {
|
||||
const [channel, member] = await Promise.all([
|
||||
|
|
@ -246,9 +246,9 @@ export async function fetchChannelAndMyMember(channelId: string): Promise<Array<
|
|||
return actions;
|
||||
}
|
||||
|
||||
export async function getAddedDmUsersIfNecessary(state: GlobalState, preferences: PreferenceType[]): Promise<Array<GenericAction>> {
|
||||
export async function getAddedDmUsersIfNecessary(state: GlobalState, preferences: PreferenceType[]): Promise<GenericAction[]> {
|
||||
const userIds: string[] = [];
|
||||
const actions: Array<GenericAction> = [];
|
||||
const actions: GenericAction[] = [];
|
||||
|
||||
for (const preference of preferences) {
|
||||
if (preference.category === Preferences.CATEGORY_DIRECT_CHANNEL_SHOW && preference.value === 'true') {
|
||||
|
|
@ -319,7 +319,7 @@ export function lastChannelIdForTeam(state: GlobalState, teamId: string): string
|
|||
return firstChannel;
|
||||
}
|
||||
|
||||
function fetchDirectMessageProfileIfNeeded(state: GlobalState, channel: Channel, channelMembers: Array<ChannelMembership>, profilesInChannel: Array<string>) {
|
||||
function fetchDirectMessageProfileIfNeeded(state: GlobalState, channel: Channel, channelMembers: ChannelMembership[], profilesInChannel: string[]) {
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const myPreferences = getMyPreferences(state);
|
||||
const users = getUsers(state);
|
||||
|
|
@ -351,7 +351,7 @@ function fetchDirectMessageProfileIfNeeded(state: GlobalState, channel: Channel,
|
|||
return {preferences};
|
||||
}
|
||||
|
||||
function fetchGroupMessageProfilesIfNeeded(state: GlobalState, channel: Channel, channelMembers: Array<ChannelMembership>, profilesInChannel: Array<string>) {
|
||||
function fetchGroupMessageProfilesIfNeeded(state: GlobalState, channel: Channel, channelMembers: ChannelMembership[], profilesInChannel: string[]) {
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const myPreferences = getMyPreferences(state);
|
||||
const config = getConfig(state);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export function handleChannelDeletedEvent(msg: WebSocketMessage) {
|
|||
const currentTeamId = getCurrentTeamId(state);
|
||||
const config = getConfig(state);
|
||||
const viewArchivedChannels = config.ExperimentalViewArchivedChannels === 'true';
|
||||
const actions: Array<GenericAction> = [{
|
||||
const actions: GenericAction[] = [{
|
||||
type: ChannelTypes.RECEIVED_CHANNEL_DELETED,
|
||||
data: {
|
||||
id: msg.data.channel_id,
|
||||
|
|
@ -94,7 +94,7 @@ export function handleChannelMemberUpdatedEvent(msg: WebSocketMessage) {
|
|||
try {
|
||||
const channelMember = JSON.parse(msg.data.channelMember);
|
||||
const rolesToLoad = channelMember.roles.split(' ');
|
||||
const actions: Array<GenericAction> = [{
|
||||
const actions: GenericAction[] = [{
|
||||
type: ChannelTypes.RECEIVED_MY_CHANNEL_MEMBER,
|
||||
data: channelMember,
|
||||
}];
|
||||
|
|
@ -129,7 +129,7 @@ export function handleChannelUnarchiveEvent(msg: WebSocketMessage) {
|
|||
const viewArchivedChannels = config.ExperimentalViewArchivedChannels === 'true';
|
||||
|
||||
if (msg.broadcast.team_id === currentTeamId) {
|
||||
const actions: Array<GenericAction> = [{
|
||||
const actions: GenericAction[] = [{
|
||||
type: ChannelTypes.RECEIVED_CHANNEL_UNARCHIVED,
|
||||
data: {
|
||||
id: msg.data.channel_id,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {ActionResult, DispatchFunc, batchActions} from '@mm-redux/types/actions'
|
|||
import {WebSocketMessage} from '@mm-redux/types/websocket';
|
||||
|
||||
export function handleGroupUpdatedEvent(msg: WebSocketMessage) {
|
||||
return (dispatch: DispatchFunc) : ActionResult => {
|
||||
return (dispatch: DispatchFunc): ActionResult => {
|
||||
const data = JSON.parse(msg.data.group);
|
||||
dispatch(batchActions([
|
||||
{
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ export function doFirstConnect(now: number) {
|
|||
return async (dispatch: DispatchFunc, getState: GetStateFunc): Promise<ActionResult> => {
|
||||
const state = getState();
|
||||
const {lastDisconnectAt} = state.websocket;
|
||||
const actions: Array<GenericAction> = [wsConnected(now)];
|
||||
const actions: GenericAction[] = [wsConnected(now)];
|
||||
|
||||
if (lastDisconnectAt) {
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
|
|
@ -150,7 +150,7 @@ export function doReconnect(now: number) {
|
|||
const currentUserId = getCurrentUserId(state);
|
||||
const users = getUsers(state);
|
||||
const {lastDisconnectAt} = state.websocket;
|
||||
const actions: Array<GenericAction> = [];
|
||||
const actions: GenericAction[] = [];
|
||||
|
||||
dispatch(batchActions([
|
||||
wsConnected(now),
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export function handleNewPostEvent(msg: WebSocketMessage) {
|
|||
ownPost: data.user_id === currentUserId,
|
||||
};
|
||||
|
||||
const actions: Array<GenericAction> = [];
|
||||
const actions: GenericAction[] = [];
|
||||
|
||||
const exists = selectPost(state, post.pending_post_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {WebSocketMessage} from '@mm-redux/types/websocket';
|
|||
export function handlePreferenceChangedEvent(msg: WebSocketMessage) {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc): Promise<ActionResult> => {
|
||||
const preference = JSON.parse(msg.data.preference);
|
||||
const actions: Array<GenericAction> = [{
|
||||
const actions: GenericAction[] = [{
|
||||
type: PreferenceTypes.RECEIVED_PREFERENCES,
|
||||
data: [preference],
|
||||
}];
|
||||
|
|
@ -36,7 +36,7 @@ export function handlePreferencesChangedEvent(msg: WebSocketMessage) {
|
|||
return async (dispatch: DispatchFunc, getState: GetStateFunc): Promise<ActionResult> => {
|
||||
const preferences: PreferenceType[] = JSON.parse(msg.data.preferences);
|
||||
const posts = getAllPosts(getState());
|
||||
const actions: Array<GenericAction> = [{
|
||||
const actions: GenericAction[] = [{
|
||||
type: PreferenceTypes.RECEIVED_PREFERENCES,
|
||||
data: preferences,
|
||||
}];
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export function handleLeaveTeamEvent(msg: Partial<WebSocketMessage>) {
|
|||
const currentUser = getCurrentUser(state);
|
||||
|
||||
if (currentUser.id === msg.data.user_id) {
|
||||
const actions: Array<GenericAction> = [{type: TeamTypes.LEAVE_TEAM, data: teams[msg.data.team_id]}];
|
||||
const actions: GenericAction[] = [{type: TeamTypes.LEAVE_TEAM, data: teams[msg.data.team_id]}];
|
||||
if (isGuest(currentUser.roles)) {
|
||||
const notVisible = await notVisibleUsersActions(state);
|
||||
if (notVisible.length) {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export function handleUserAddedEvent(msg: WebSocketMessage) {
|
|||
const currentTeamId = getCurrentTeamId(state);
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
const teamId = msg.data.team_id;
|
||||
const actions: Array<GenericAction> = [{
|
||||
const actions: GenericAction[] = [{
|
||||
type: ChannelTypes.CHANNEL_MEMBER_ADDED,
|
||||
data: {
|
||||
channel_id: msg.broadcast.channel_id,
|
||||
|
|
@ -71,7 +71,7 @@ export function handleUserRemovedEvent(msg: WebSocketMessage) {
|
|||
const currentChannelId = getCurrentChannelId(state);
|
||||
const currentTeamId = getCurrentTeamId(state);
|
||||
const currentUser = getCurrentUser(state);
|
||||
const actions: Array<GenericAction> = [];
|
||||
const actions: GenericAction[] = [];
|
||||
let channelId;
|
||||
let userId;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const ClientApps = (superclass: any) => class extends superclass {
|
|||
`${this.getAppsProxyRoute()}/api/v1/call`,
|
||||
{method: 'post', body: JSON.stringify(callCopy)},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
getAppsBindings = async (userID: string, channelID: string, teamID: string) => {
|
||||
const params = {
|
||||
|
|
@ -39,7 +39,7 @@ const ClientApps = (superclass: any) => class extends superclass {
|
|||
`${this.getAppsProxyRoute()}/api/v1/bindings${buildQueryString(params)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientApps;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ export default class ClientBase {
|
|||
|
||||
getWebSocketUrl = () => {
|
||||
return `${this.getBaseRoute()}/websocket`;
|
||||
}
|
||||
};
|
||||
|
||||
setAcceptLanguage(locale: string) {
|
||||
this.defaultHeaders['Accept-Language'] = locale;
|
||||
|
|
|
|||
|
|
@ -19,21 +19,21 @@ const ClientBots = (superclass: any) => class extends superclass {
|
|||
`${this.getBotRoute(botUserId)}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
getBots = async (page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getBotsRoute()}${buildQueryString({page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
getBotsIncludeDeleted = async (page = 0, perPage = PER_PAGE_DEFAULT) => {
|
||||
return this.doFetch(
|
||||
`${this.getBotsRoute()}${buildQueryString({include_deleted: true, page, per_page: perPage})}`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientBots;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ const ClientFiles = (superclass: any) => class extends superclass {
|
|||
`${this.getFileRoute(fileId)}/link`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientFiles;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const ClientGroups = (superclass: any) => class extends superclass {
|
|||
`${this.getUsersRoute()}/${userID}/groups`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
getAllGroupsAssociatedToTeam = async (teamID: string, filterAllowReference = false) => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/teams/${teamID}/groups${buildQueryString({paginate: false, filter_allow_reference: filterAllowReference})}`,
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ const ClientPosts = (superclass: any) => class extends superclass {
|
|||
`${this.getUserRoute(userId)}/posts/${postId}/set_unread`,
|
||||
{method: 'post', body: JSON.stringify({collapsed_threads_supported: true})},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
pinPost = async (postId: string) => {
|
||||
analytics.trackAPI('api_posts_pin');
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ const ClientTos = (superclass: any) => class extends superclass {
|
|||
`${this.getUserRoute('me')}/terms_of_service`,
|
||||
{method: 'post', body: JSON.stringify({termsOfServiceId, accepted})},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
getTermsOfService = async () => {
|
||||
return this.doFetch(
|
||||
`${this.getBaseRoute()}/terms_of_service`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default ClientTos;
|
||||
|
|
|
|||
|
|
@ -66,14 +66,14 @@ const ClientUsers = (superclass: any) => class extends superclass {
|
|||
`${this.getUsersRoute()}${buildQueryString(queryParams)}`,
|
||||
{method: 'post', body: JSON.stringify(user)},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
patchMe = async (userPatch: Partial<UserProfile>) => {
|
||||
return this.doFetch(
|
||||
`${this.getUserRoute('me')}/patch`,
|
||||
{method: 'put', body: JSON.stringify(userPatch)},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
patchUser = async (userPatch: Partial<UserProfile> & {id: string}) => {
|
||||
analytics.trackAPI('api_users_patch');
|
||||
|
|
@ -82,7 +82,7 @@ const ClientUsers = (superclass: any) => class extends superclass {
|
|||
`${this.getUserRoute(userPatch.id)}/patch`,
|
||||
{method: 'put', body: JSON.stringify(userPatch)},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
updateUser = async (user: UserProfile) => {
|
||||
analytics.trackAPI('api_users_update');
|
||||
|
|
@ -91,7 +91,7 @@ const ClientUsers = (superclass: any) => class extends superclass {
|
|||
`${this.getUserRoute(user.id)}`,
|
||||
{method: 'put', body: JSON.stringify(user)},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
demoteUserToGuest = async (userId: string) => {
|
||||
analytics.trackAPI('api_users_demote_user_to_guest');
|
||||
|
|
@ -100,7 +100,7 @@ const ClientUsers = (superclass: any) => class extends superclass {
|
|||
`${this.getUserRoute(userId)}/demote`,
|
||||
{method: 'post'},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
getKnownUsers = async () => {
|
||||
analytics.trackAPI('api_get_known_users');
|
||||
|
|
@ -108,7 +108,7 @@ const ClientUsers = (superclass: any) => class extends superclass {
|
|||
`${this.getUsersRoute()}/known`,
|
||||
{method: 'get'},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
sendPasswordResetEmail = async (email: string) => {
|
||||
analytics.trackAPI('api_users_send_password_reset');
|
||||
|
|
@ -117,7 +117,7 @@ const ClientUsers = (superclass: any) => class extends superclass {
|
|||
`${this.getUsersRoute()}/password/reset/send`,
|
||||
{method: 'post', body: JSON.stringify({email})},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
setDefaultProfileImage = async (userId: string) => {
|
||||
analytics.trackAPI('api_users_set_default_profile_picture');
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ export default class AtMention extends React.PureComponent {
|
|||
this.setState({
|
||||
user,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {isSearchResult, mentionName, mentionStyle, onPostPress, teammateNameDisplay, textStyle, mentionKeys, theme} = this.props;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ export default class AttachmentButton extends PureComponent {
|
|||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
attachPhotoFromCamera = () => {
|
||||
return this.attachFileFromCamera('camera', 'photo');
|
||||
|
|
@ -274,7 +274,7 @@ export default class AttachmentButton extends PureComponent {
|
|||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
};
|
||||
|
||||
hasPhotoPermission = async (source, mediaType = '') => {
|
||||
if (Platform.OS === 'ios') {
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ export default class Autocomplete extends PureComponent {
|
|||
|
||||
handleAppCommandCountChange = (appCommandCount) => {
|
||||
this.setState({appCommandCount});
|
||||
}
|
||||
};
|
||||
|
||||
handleCommandCountChange = (commandCount) => {
|
||||
this.setState({commandCount});
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ export default class DateSuggestion extends PureComponent {
|
|||
|
||||
setCalendarActive = (active) => {
|
||||
this.setState({active});
|
||||
}
|
||||
};
|
||||
|
||||
completeMention = (day) => {
|
||||
const mention = day.dateString;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
getItemLayout = ({index}) => ({length: 40, offset: 40 * index, index})
|
||||
getItemLayout = ({index}) => ({length: 40, offset: 40 * index, index});
|
||||
|
||||
keyExtractor = (item) => item;
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ export default class EmojiSuggestion extends PureComponent {
|
|||
});
|
||||
|
||||
this.props.onResultCountChange(0);
|
||||
}
|
||||
};
|
||||
|
||||
searchEmojis = (searchTerm) => {
|
||||
const {emojis} = this.props;
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ export class ParsedCommand {
|
|||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// parseForm parses the rest of the command using the previously matched form.
|
||||
public parseForm = (autocompleteMode = false): ParsedCommand => {
|
||||
|
|
@ -597,7 +597,7 @@ export class ParsedCommand {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class AppCommandParser {
|
||||
|
|
@ -649,7 +649,7 @@ export class AppCommandParser {
|
|||
}
|
||||
|
||||
return this.composeCallFromParsed(parsed);
|
||||
}
|
||||
};
|
||||
|
||||
private async addDefaultAndReadOnlyValues(parsed: ParsedCommand) {
|
||||
if (!parsed.form?.fields) {
|
||||
|
|
@ -738,7 +738,7 @@ export class AppCommandParser {
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// getSuggestions returns suggestions for subcommands and/or form arguments
|
||||
public getSuggestions = async (pretext: string): Promise<ExtendedAutocompleteSuggestion[]> => {
|
||||
|
|
@ -790,7 +790,7 @@ export class AppCommandParser {
|
|||
suggestions = this.getNoMatchingSuggestion();
|
||||
}
|
||||
return suggestions.map((suggestion) => this.decorateSuggestionComplete(parsed, suggestion));
|
||||
}
|
||||
};
|
||||
|
||||
getNoMatchingSuggestion = () => {
|
||||
return [{
|
||||
|
|
@ -803,7 +803,7 @@ export class AppCommandParser {
|
|||
IconData: COMMAND_SUGGESTION_ERROR,
|
||||
Description: '',
|
||||
}];
|
||||
}
|
||||
};
|
||||
|
||||
getErrorSuggestion = (parsed: ParsedCommand) => {
|
||||
return [{
|
||||
|
|
@ -816,7 +816,7 @@ export class AppCommandParser {
|
|||
IconData: COMMAND_SUGGESTION_ERROR,
|
||||
Description: parsed.error,
|
||||
}];
|
||||
}
|
||||
};
|
||||
|
||||
// composeCallFromParsed creates the form submission call
|
||||
private composeCallFromParsed = async (parsed: ParsedCommand): Promise<{call: AppCallRequest | null; errorMessage?: string}> => {
|
||||
|
|
@ -846,7 +846,7 @@ export class AppCommandParser {
|
|||
|
||||
const context = this.getAppContext(parsed.binding);
|
||||
return {call: createCallRequest(call, context, {}, values, parsed.command)};
|
||||
}
|
||||
};
|
||||
|
||||
private expandOptions = async (parsed: ParsedCommand, values: AppCallValues): Promise<{errorMessage?: string}> => {
|
||||
if (!parsed.form?.fields) {
|
||||
|
|
@ -935,7 +935,7 @@ export class AppCommandParser {
|
|||
errorMessage = errorMessage + errors[v] + '\n';
|
||||
});
|
||||
return {errorMessage};
|
||||
}
|
||||
};
|
||||
|
||||
// decorateSuggestionComplete applies the necessary modifications for a suggestion to be processed
|
||||
private decorateSuggestionComplete = (parsed: ParsedCommand, choice: AutocompleteSuggestion): AutocompleteSuggestion => {
|
||||
|
|
@ -956,7 +956,7 @@ export class AppCommandParser {
|
|||
...choice,
|
||||
Complete: complete,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// getCommandBindings returns the commands in the redux store.
|
||||
// They are grouped by app id since each app has one base command
|
||||
|
|
@ -966,19 +966,19 @@ export class AppCommandParser {
|
|||
return getRHSCommandBindings(state);
|
||||
}
|
||||
return getCommandBindings(state);
|
||||
}
|
||||
};
|
||||
|
||||
// getChannel gets the channel in which the user is typing the command
|
||||
private getChannel = (): Channel | null => {
|
||||
const state = this.store.getState();
|
||||
return selectChannel(state, this.channelID);
|
||||
}
|
||||
};
|
||||
|
||||
public setChannelContext = (channelID: string, teamID = '', rootPostID?: string) => {
|
||||
this.channelID = channelID;
|
||||
this.rootPostID = rootPostID;
|
||||
this.teamID = teamID;
|
||||
}
|
||||
};
|
||||
|
||||
// isAppCommand determines if subcommand/form suggestions need to be returned.
|
||||
// When this returns true, the caller knows that the parser should handle all suggestions for the current command string.
|
||||
|
|
@ -1000,7 +1000,7 @@ export class AppCommandParser {
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// getAppContext collects post/channel/team info for performing calls
|
||||
private getAppContext = (binding: AppBinding): AppContext => {
|
||||
|
|
@ -1019,7 +1019,7 @@ export class AppCommandParser {
|
|||
context.team_id = channel.team_id || getCurrentTeamId(this.store.getState());
|
||||
|
||||
return context;
|
||||
}
|
||||
};
|
||||
|
||||
// fetchForm unconditionaly retrieves the form for the given binding (subcommand)
|
||||
private fetchForm = async (binding: AppBinding): Promise<{form?: AppForm; error?: string} | undefined> => {
|
||||
|
|
@ -1066,7 +1066,7 @@ export class AppCommandParser {
|
|||
}
|
||||
|
||||
return {form: callResponse.form};
|
||||
}
|
||||
};
|
||||
|
||||
public getForm = async (location: string, binding: AppBinding): Promise<{form?: AppForm; error?: string} | undefined> => {
|
||||
const rootID = this.rootPostID || '';
|
||||
|
|
@ -1088,7 +1088,7 @@ export class AppCommandParser {
|
|||
});
|
||||
}
|
||||
return fetched;
|
||||
}
|
||||
};
|
||||
|
||||
// getSuggestionsForSubCommands returns suggestions for a subcommand's name
|
||||
private getCommandSuggestions = (parsed: ParsedCommand): AutocompleteSuggestion[] => {
|
||||
|
|
@ -1111,7 +1111,7 @@ export class AppCommandParser {
|
|||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// getParameterSuggestions computes suggestions for positional argument values, flag names, and flag argument values
|
||||
private getParameterSuggestions = async (parsed: ParsedCommand): Promise<ExtendedAutocompleteSuggestion[]> => {
|
||||
|
|
@ -1149,7 +1149,7 @@ export class AppCommandParser {
|
|||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
// getMissingFields collects the required fields that were not supplied in a submission
|
||||
private getMissingFields = (parsed: ParsedCommand): AppField[] => {
|
||||
|
|
@ -1169,7 +1169,7 @@ export class AppCommandParser {
|
|||
}
|
||||
|
||||
return missing;
|
||||
}
|
||||
};
|
||||
|
||||
// getFlagNameSuggestions returns suggestions for flag names
|
||||
private getFlagNameSuggestions = (parsed: ParsedCommand): AutocompleteSuggestion[] => {
|
||||
|
|
@ -1201,7 +1201,7 @@ export class AppCommandParser {
|
|||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
// getSuggestionsForField gets suggestions for a positional or flag field value
|
||||
private getValueSuggestions = async (parsed: ParsedCommand, delimiter?: string): Promise<ExtendedAutocompleteSuggestion[]> => {
|
||||
|
|
@ -1242,7 +1242,7 @@ export class AppCommandParser {
|
|||
Hint: '',
|
||||
IconData: parsed.binding?.icon || '',
|
||||
}];
|
||||
}
|
||||
};
|
||||
|
||||
// getStaticSelectSuggestions returns suggestions specified in the field's options property
|
||||
private getStaticSelectSuggestions = (parsed: ParsedCommand, delimiter?: string): AutocompleteSuggestion[] => {
|
||||
|
|
@ -1275,7 +1275,7 @@ export class AppCommandParser {
|
|||
IconData: opt.icon_data || parsed.binding?.icon || '',
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// getDynamicSelectSuggestions fetches and returns suggestions from the server
|
||||
private getDynamicSelectSuggestions = async (parsed: ParsedCommand, delimiter?: string): Promise<AutocompleteSuggestion[]> => {
|
||||
|
|
@ -1364,7 +1364,7 @@ export class AppCommandParser {
|
|||
IconData: s.icon_data || parsed.binding?.icon || '',
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
private makeDynamicSelectSuggestionError = (message: string): AutocompleteSuggestion[] => {
|
||||
const errMsg = this.intl.formatMessage({
|
||||
|
|
@ -1383,7 +1383,7 @@ export class AppCommandParser {
|
|||
IconData: COMMAND_SUGGESTION_ERROR,
|
||||
Description: errMsg,
|
||||
}];
|
||||
}
|
||||
};
|
||||
|
||||
private getUserFieldSuggestions = async (parsed: ParsedCommand): Promise<AutocompleteSuggestion[]> => {
|
||||
let input = parsed.incomplete.trim();
|
||||
|
|
@ -1392,7 +1392,7 @@ export class AppCommandParser {
|
|||
}
|
||||
const {data} = await this.store.dispatch(autocompleteUsersInChannel(input, this.channelID));
|
||||
return getUserSuggestions(data);
|
||||
}
|
||||
};
|
||||
|
||||
private getChannelFieldSuggestions = async (parsed: ParsedCommand): Promise<AutocompleteSuggestion[]> => {
|
||||
let input = parsed.incomplete.trim();
|
||||
|
|
@ -1401,7 +1401,7 @@ export class AppCommandParser {
|
|||
}
|
||||
const {data} = await this.store.dispatch(autocompleteChannels(this.teamID, input));
|
||||
return getChannelSuggestions(data);
|
||||
}
|
||||
};
|
||||
|
||||
// getBooleanSuggestions returns true/false suggestions
|
||||
private getBooleanSuggestions = (parsed: ParsedCommand): AutocompleteSuggestion[] => {
|
||||
|
|
@ -1426,7 +1426,7 @@ export class AppCommandParser {
|
|||
});
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isMultiword(value: string) {
|
||||
|
|
|
|||
|
|
@ -109,13 +109,13 @@ export default class AppSlashSuggestion extends PureComponent<Props, State> {
|
|||
isAppCommand = (pretext: string, channelID: string, teamID = '', rootID?: string) => {
|
||||
this.appCommandParser.setChannelContext(channelID, teamID, rootID);
|
||||
return this.appCommandParser.isAppCommand(pretext);
|
||||
}
|
||||
};
|
||||
|
||||
fetchAndShowAppCommandSuggestions = async (pretext: string, channelID: string, teamID = '', rootID?: string) => {
|
||||
this.appCommandParser.setChannelContext(channelID, teamID, rootID);
|
||||
const suggestions = await this.appCommandParser.getSuggestions(pretext);
|
||||
this.updateSuggestions(suggestions);
|
||||
}
|
||||
};
|
||||
|
||||
updateSuggestions = (matches: ExtendedAutocompleteSuggestion[]) => {
|
||||
this.setState({
|
||||
|
|
@ -123,7 +123,7 @@ export default class AppSlashSuggestion extends PureComponent<Props, State> {
|
|||
dataSource: matches,
|
||||
});
|
||||
this.props.onResultCountChange(matches.length);
|
||||
}
|
||||
};
|
||||
|
||||
completeSuggestion = (command: string) => {
|
||||
const {onChangeText} = this.props;
|
||||
|
|
@ -157,13 +157,13 @@ export default class AppSlashSuggestion extends PureComponent<Props, State> {
|
|||
return () => {
|
||||
this.completeSuggestion(base);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
completeChannelMention = (base: string): (channelName: string) => void => {
|
||||
return () => {
|
||||
this.completeSuggestion(base);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
keyExtractor = (item: ExtendedAutocompleteSuggestion): string => item.Suggestion + item.type + item.item;
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ export default class AppSlashSuggestion extends PureComponent<Props, State> {
|
|||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {maxListHeight, theme, nestedScrollEnabled} = this.props;
|
||||
|
|
|
|||
|
|
@ -144,13 +144,13 @@ export default class SlashSuggestion extends PureComponent<Props, State> {
|
|||
});
|
||||
|
||||
this.updateSuggestions(matches);
|
||||
}
|
||||
};
|
||||
|
||||
getAppBaseCommandSuggestions = (pretext: string, channelID: string, teamID = '', rootID?: string): AutocompleteSuggestion[] => {
|
||||
this.appCommandParser.setChannelContext(channelID, teamID, rootID);
|
||||
const suggestions = this.appCommandParser.getSuggestionsBase(pretext);
|
||||
return suggestions;
|
||||
}
|
||||
};
|
||||
|
||||
updateSuggestions = (matches: AutocompleteSuggestion[]) => {
|
||||
this.setState({
|
||||
|
|
@ -158,7 +158,7 @@ export default class SlashSuggestion extends PureComponent<Props, State> {
|
|||
dataSource: matches,
|
||||
});
|
||||
this.props.onResultCountChange(matches.length);
|
||||
}
|
||||
};
|
||||
|
||||
filterCommands = (matchTerm: string, commands: Command[]): AutocompleteSuggestion[] => {
|
||||
const data = commands.filter((command) => {
|
||||
|
|
@ -179,11 +179,11 @@ export default class SlashSuggestion extends PureComponent<Props, State> {
|
|||
IconData: item.icon_url || item.autocomplete_icon_data || '',
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
contains = (matches: AutocompleteSuggestion[], complete: string): boolean => {
|
||||
return matches.findIndex((match) => match.Complete === complete) !== -1;
|
||||
}
|
||||
};
|
||||
|
||||
completeSuggestion = (command: string) => {
|
||||
const {onChangeText} = this.props;
|
||||
|
|
@ -219,7 +219,7 @@ export default class SlashSuggestion extends PureComponent<Props, State> {
|
|||
complete={item.Complete}
|
||||
icon={item.IconData}
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
||||
render() {
|
||||
const {maxListHeight, theme, nestedScrollEnabled} = this.props;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ export default class ChannelLink extends React.PureComponent {
|
|||
this.props.onChannelLinkPress(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const channel = this.state.channel;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ export default class ChannelLoader extends PureComponent {
|
|||
delay: 500,
|
||||
useNativeDriver: false,
|
||||
}).start();
|
||||
}
|
||||
};
|
||||
|
||||
buildSections({key, style, bg, color}) {
|
||||
return (
|
||||
|
|
@ -128,7 +128,7 @@ export default class ChannelLoader extends PureComponent {
|
|||
const {height} = e.nativeEvent.layout;
|
||||
const maxRows = calculateMaxRows(height);
|
||||
this.setState({maxRows});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ export default class EditChannelInfo extends PureComponent {
|
|||
|
||||
onHeaderLayout = ({nativeEvent}) => {
|
||||
this.setState({headerPosition: nativeEvent.layout.y});
|
||||
}
|
||||
};
|
||||
|
||||
onKeyboardDidShow = () => {
|
||||
this.setState({keyboardVisible: true});
|
||||
|
|
@ -172,15 +172,15 @@ export default class EditChannelInfo extends PureComponent {
|
|||
this.setState({headerHasFocus: false});
|
||||
this.scrollHeaderToTop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onKeyboardDidHide = () => {
|
||||
this.setState({keyboardVisible: false});
|
||||
}
|
||||
};
|
||||
|
||||
onKeyboardOffsetChanged = (keyboardPosition) => {
|
||||
this.setState({keyboardPosition});
|
||||
}
|
||||
};
|
||||
|
||||
onHeaderFocus = () => {
|
||||
if (this.state.keyboardVisible) {
|
||||
|
|
@ -194,7 +194,7 @@ export default class EditChannelInfo extends PureComponent {
|
|||
if (this.scroll.current) {
|
||||
this.scroll.current.scrollTo({x: 0, y: this.state.headerPosition});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ export default class EmojiPicker extends PureComponent {
|
|||
|
||||
setSearchBarRef = (ref) => {
|
||||
this.searchBarRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
setSectionListRef = (ref) => {
|
||||
this.sectionListRef = ref;
|
||||
|
|
@ -121,7 +121,7 @@ export default class EmojiPicker extends PureComponent {
|
|||
const emojis = this.renderableEmojis(this.props.emojisBySection, this.props.deviceWidth);
|
||||
this.setState({emojis});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
renderableEmojis = (emojis, deviceWidth) => {
|
||||
const numberOfColumns = this.getNumberOfColumns(deviceWidth);
|
||||
|
|
@ -501,7 +501,7 @@ export default class EmojiPicker extends PureComponent {
|
|||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const getStyleSheetFromTheme = makeStyleSheetFromTheme((theme) => {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default class EmojiPickerRow extends Component {
|
|||
emojiSize: PropTypes.number.isRequired,
|
||||
items: PropTypes.array.isRequired,
|
||||
onEmojiPress: PropTypes.func.isRequired,
|
||||
}
|
||||
};
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return !shallowEqual(this.props.items, nextProps.items);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export default class ErrorList extends PureComponent {
|
|||
clearErrors: PropTypes.func.isRequired,
|
||||
}).isRequired,
|
||||
errors: PropTypes.array.isRequired,
|
||||
}
|
||||
};
|
||||
|
||||
renderErrorsList() {
|
||||
const {errors} = this.props;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class FormattedMarkdownText extends React.PureComponent {
|
|||
|
||||
createParser = () => {
|
||||
return new Parser();
|
||||
}
|
||||
};
|
||||
|
||||
createRenderer = () => {
|
||||
return new Renderer({
|
||||
|
|
@ -73,39 +73,39 @@ class FormattedMarkdownText extends React.PureComponent {
|
|||
atMention: this.renderAtMention,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
computeTextStyle = (baseStyle, context) => {
|
||||
return concatStyles(baseStyle, context.map((type) => this.textStyles[type]));
|
||||
}
|
||||
};
|
||||
|
||||
renderText = ({context, literal}) => {
|
||||
const style = this.computeTextStyle(this.props.style || this.baseTextStyle, context);
|
||||
return <Text style={style}>{literal}</Text>;
|
||||
}
|
||||
};
|
||||
|
||||
renderCodeSpan = ({context, literal}) => {
|
||||
const style = this.computeTextStyle([this.baseTextStyle, this.textStyles.code], context);
|
||||
return <Text style={style}>{literal}</Text>;
|
||||
}
|
||||
};
|
||||
|
||||
renderLink = ({children, href}) => {
|
||||
const url = href[0] === TARGET_BLANK_URL_PREFIX ? href.substring(1, href.length) : href;
|
||||
return <MarkdownLink href={url}>{children}</MarkdownLink>;
|
||||
}
|
||||
};
|
||||
|
||||
renderBreak = () => {
|
||||
return <Text>{'\n'}</Text>;
|
||||
}
|
||||
};
|
||||
|
||||
renderParagraph = ({children}) => {
|
||||
return <Text>{children}</Text>;
|
||||
}
|
||||
};
|
||||
|
||||
renderHTML = (props) => {
|
||||
console.warn(`HTML used in FormattedMarkdownText component with id ${this.props.id}`); // eslint-disable-line no-console
|
||||
return this.renderText(props);
|
||||
}
|
||||
};
|
||||
|
||||
renderAtMention = ({context, mentionName}) => {
|
||||
const style = getStyleSheet(this.props.theme);
|
||||
|
|
@ -118,7 +118,7 @@ class FormattedMarkdownText extends React.PureComponent {
|
|||
textStyle={[this.computeTextStyle(this.props.baseTextStyle, context), style.atMentionOpacity]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {id, defaultMessage, values, theme} = this.props;
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ type Props = {
|
|||
markAllThreadsInTeamRead: (userId: $ID<UserProfile>, teamId: $ID<Team>) => void;
|
||||
selectPost: (postId: string) => void;
|
||||
};
|
||||
allThreadIds: $ID<UserThread>[];
|
||||
allThreadIds: Array<$ID<UserThread>>;
|
||||
intl: typeof intlShape;
|
||||
teamId: $ID<Team>;
|
||||
theme: Theme;
|
||||
threadCount: ThreadsState['counts'][$ID<Team>];
|
||||
unreadThreadIds: $ID<UserThread>[];
|
||||
unreadThreadIds: Array<$ID<UserThread>>;
|
||||
userId: $ID<UserProfile>;
|
||||
viewingUnreads: boolean;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export type Props = {
|
|||
onRefresh: () => void;
|
||||
testID: string;
|
||||
theme: Theme;
|
||||
threadIds: $ID<UserThread>[];
|
||||
threadIds: Array<$ID<UserThread>>;
|
||||
viewAllThreads: () => void;
|
||||
viewUnreadThreads: () => void;
|
||||
viewingUnreads: boolean;
|
||||
|
|
|
|||
|
|
@ -92,13 +92,13 @@ export default class InteractiveDialogController extends PureComponent {
|
|||
};
|
||||
|
||||
showModal('InteractiveDialog', dialog.title, null, options);
|
||||
}
|
||||
};
|
||||
|
||||
handleCancel = (dialog, url) => {
|
||||
if (dialog.notify_on_cancel) {
|
||||
this.props.actions.submitInteractiveDialog({...dialog, url, cancelled: true});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export default class MarkdownEmoji extends PureComponent {
|
|||
|
||||
createParser = () => {
|
||||
return new Parser();
|
||||
}
|
||||
};
|
||||
|
||||
createRenderer = () => {
|
||||
return new Renderer({
|
||||
|
|
@ -80,7 +80,7 @@ export default class MarkdownEmoji extends PureComponent {
|
|||
renderNewLine = ({context}) => {
|
||||
const style = this.computeTextStyle(this.props.baseTextStyle, context);
|
||||
return <Text style={style}>{'\n'}</Text>;
|
||||
}
|
||||
};
|
||||
|
||||
renderEditedIndicator = ({context}) => {
|
||||
let spacer = '';
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export default class MarkdownTable extends React.PureComponent {
|
|||
setMaxPreviewColumns = ({window}) => {
|
||||
const maxPreviewColumns = Math.floor(window.width / CELL_MIN_WIDTH);
|
||||
this.setState({maxPreviewColumns});
|
||||
}
|
||||
};
|
||||
|
||||
getTableWidth = (isFullView = false) => {
|
||||
const maxPreviewColumns = this.state.maxPreviewColumns || MAX_PREVIEW_COLUMNS;
|
||||
|
|
@ -97,7 +97,7 @@ export default class MarkdownTable extends React.PureComponent {
|
|||
|
||||
renderPreviewRows = (isFullView = false) => {
|
||||
return this.renderRows(isFullView, true);
|
||||
}
|
||||
};
|
||||
|
||||
shouldRenderAsFlex = (isFullView = false) => {
|
||||
const {numColumns} = this.props;
|
||||
|
|
@ -123,7 +123,7 @@ export default class MarkdownTable extends React.PureComponent {
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
getTableStyle = (isFullView) => {
|
||||
const {theme} = this.props;
|
||||
|
|
@ -138,7 +138,7 @@ export default class MarkdownTable extends React.PureComponent {
|
|||
|
||||
tableStyle.push({width: this.getTableWidth(isFullView)});
|
||||
return tableStyle;
|
||||
}
|
||||
};
|
||||
|
||||
renderRows = (isFullView = false, isPreview = false) => {
|
||||
const tableStyle = this.getTableStyle(isFullView);
|
||||
|
|
@ -180,7 +180,7 @@ export default class MarkdownTable extends React.PureComponent {
|
|||
{rows}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {containerWidth, contentHeight} = this.state;
|
||||
|
|
|
|||
|
|
@ -46,14 +46,7 @@ const styles = StyleSheet.create({
|
|||
height: ViewTypes.INDICATOR_BAR_HEIGHT,
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
...Platform.select({
|
||||
android: {
|
||||
elevation: 9,
|
||||
},
|
||||
ios: {
|
||||
zIndex: 9,
|
||||
},
|
||||
}),
|
||||
zIndex: 9,
|
||||
},
|
||||
wrapper: {
|
||||
alignItems: 'center',
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ exports[`PostDraft Should render the Archived for channelIsArchived 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
@ -176,7 +175,6 @@ exports[`PostDraft Should render the Archived for deactivatedChannel 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
@ -218,7 +216,6 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
>
|
||||
<View
|
||||
collapsable={false}
|
||||
nativeID="animatedComponent"
|
||||
style={
|
||||
Object {
|
||||
"bottom": 0,
|
||||
|
|
@ -347,7 +344,6 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
collapsable={false}
|
||||
forwardedRef={[Function]}
|
||||
isInteraction={true}
|
||||
nativeID="animatedComponent"
|
||||
style={
|
||||
Object {
|
||||
"display": "flex",
|
||||
|
|
@ -379,7 +375,6 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
collapsable={false}
|
||||
forwardedRef={[Function]}
|
||||
isInteraction={true}
|
||||
nativeID="animatedComponent"
|
||||
style={
|
||||
Object {
|
||||
"height": 0,
|
||||
|
|
@ -427,7 +422,6 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
@ -460,7 +454,6 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
@ -493,7 +486,6 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
@ -526,7 +518,6 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
@ -559,7 +550,6 @@ exports[`PostDraft Should render the DraftInput 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export default class Archived extends PureComponent {
|
|||
selectPenultimateChannel: PropTypes.func.isRequired,
|
||||
teamId: PropTypes.string.isRequired,
|
||||
theme: PropTypes.object.isRequired,
|
||||
}
|
||||
};
|
||||
|
||||
onCloseChannelPress = () => {
|
||||
const {rootId, teamId} = this.props;
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ export default class DraftInput extends PureComponent {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleInputQuickAction = (inputValue) => {
|
||||
if (this.input.current) {
|
||||
|
|
@ -363,7 +363,7 @@ export default class DraftInput extends PureComponent {
|
|||
this.input.current.setValue(value, autocomplete);
|
||||
this.updateCanSubmit();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
showSendToAllOrChannelOrHereAlert = (membersCount, msg, atHere) => {
|
||||
const {formatMessage} = this.context.intl;
|
||||
|
|
@ -396,7 +396,7 @@ export default class DraftInput extends PureComponent {
|
|||
if (canSubmit !== enabled) {
|
||||
this.setState({canSubmit: enabled});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
updateQuickActionValue = (value) => {
|
||||
if (this.quickActions.current) {
|
||||
|
|
@ -404,7 +404,7 @@ export default class DraftInput extends PureComponent {
|
|||
}
|
||||
|
||||
this.updateCanSubmit();
|
||||
}
|
||||
};
|
||||
|
||||
updateStatus = (status) => {
|
||||
const {currentUserId, setStatus} = this.props;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export default class PostInput extends PureComponent {
|
|||
theme: PropTypes.object.isRequired,
|
||||
updateInitialValue: PropTypes.func.isRequired,
|
||||
userTyping: PropTypes.func.isRequired,
|
||||
}
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -139,7 +139,7 @@ export default class PostInput extends PureComponent {
|
|||
if (this.input.current) {
|
||||
this.input.current.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getPlaceHolder = () => {
|
||||
const {rootId} = this.props;
|
||||
|
|
@ -261,11 +261,11 @@ export default class PostInput extends PureComponent {
|
|||
|
||||
onManagedConfigurationChange = (config) => {
|
||||
this.setState({disableCopyAndPaste: config.copyAndPasteProtection === 'true'});
|
||||
}
|
||||
};
|
||||
|
||||
onPaste = (error, files) => {
|
||||
EventEmitter.emit(PASTE_FILES, error, files, this.props.screenId);
|
||||
}
|
||||
};
|
||||
|
||||
resetTextInput = () => {
|
||||
if (this.input.current) {
|
||||
|
|
@ -273,7 +273,7 @@ export default class PostInput extends PureComponent {
|
|||
text: '',
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setValue = (value, autocomplete = false) => {
|
||||
this.value = value;
|
||||
|
|
@ -283,7 +283,7 @@ export default class PostInput extends PureComponent {
|
|||
});
|
||||
this.handleTextChange(value, autocomplete);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onPressIn = () => {
|
||||
if (Platform.OS === 'ios') {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ exports[`CameraButton should match snapshot 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ exports[`FileQuickAction should match snapshot 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ exports[`ImageQuickAction should match snapshot 1`] = `
|
|||
accessible={true}
|
||||
collapsable={false}
|
||||
focusable={true}
|
||||
nativeID="animatedComponent"
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default class InputQuickAction extends PureComponent {
|
|||
}
|
||||
|
||||
onTextChange(newValue);
|
||||
}
|
||||
};
|
||||
|
||||
renderInput = () => {
|
||||
const {disabled, inputType, theme} = this.props;
|
||||
|
|
@ -54,7 +54,7 @@ export default class InputQuickAction extends PureComponent {
|
|||
size={ICON_SIZE}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {testID, disabled, theme} = this.props;
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ export default class QuickActions extends PureComponent {
|
|||
handleOnTextChange = (newValue) => {
|
||||
this.handleInputEvent(newValue);
|
||||
this.props.onTextChange(newValue);
|
||||
}
|
||||
};
|
||||
|
||||
handleUploadFiles = (files) => {
|
||||
EventEmitter.emit(UPLOAD_FILES, files, this.props.screenId);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ export default class Typing extends PureComponent {
|
|||
duration,
|
||||
useNativeDriver: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderTyping = () => {
|
||||
const {typing} = this.props;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export default class UploadItem extends PureComponent {
|
|||
|
||||
handlePress = () => {
|
||||
this.props.onPress(this.props.file);
|
||||
}
|
||||
};
|
||||
|
||||
handleRetryFileUpload = (file) => {
|
||||
if (!file.failed) {
|
||||
|
|
@ -120,7 +120,7 @@ export default class UploadItem extends PureComponent {
|
|||
}
|
||||
|
||||
this.uploadFile(newFile);
|
||||
}
|
||||
};
|
||||
|
||||
uploadFile = async (file) => {
|
||||
const {channelId} = this.props;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ export default class Uploads extends PureComponent {
|
|||
const {files} = this.props;
|
||||
const index = files.indexOf(file);
|
||||
openGalleryAtIndex(index, files.filter((f) => !f.failed && !f.loading));
|
||||
}
|
||||
};
|
||||
|
||||
clearErrorsFromState = () => {
|
||||
this.setState({
|
||||
|
|
@ -126,7 +126,7 @@ export default class Uploads extends PureComponent {
|
|||
showFileMaxWarning: false,
|
||||
fileSizeWarning: null,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleAndroidBack = () => {
|
||||
const {channelId, files, handleRemoveLastFile, rootId} = this.props;
|
||||
|
|
@ -255,7 +255,7 @@ export default class Uploads extends PureComponent {
|
|||
|
||||
this.makeErrorVisible(true);
|
||||
this.hideErrorTimer = setTimeout(this.hideError, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
hideError = () => this.makeErrorVisible(false);
|
||||
|
||||
|
|
@ -270,7 +270,7 @@ export default class Uploads extends PureComponent {
|
|||
this.clearErrorsFromState();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
showOrHideContainer = () => {
|
||||
const {
|
||||
|
|
@ -286,7 +286,7 @@ export default class Uploads extends PureComponent {
|
|||
this.containerRef.current.transition(hideFiles, showFiles, 350, 'ease-in');
|
||||
this.shown = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
showPasteFilesErrorDialog = () => {
|
||||
const {formatMessage} = this.context.intl;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ type MoreMessagesButtonProps = {
|
|||
newMessageLineIndex: number;
|
||||
postIds: string[];
|
||||
registerScrollEndIndexListener: (fn: (endIndex: number) => void) => () => void;
|
||||
registerViewableItemsListener: (fn: (viewableItems: ViewToken[]) => void) => () =>void;
|
||||
registerViewableItemsListener: (fn: (viewableItems: ViewToken[]) => void) => () => void;
|
||||
resetUnreadMessageCount: (channelId: string) => void;
|
||||
scrollToIndex: (index: number, animated?: boolean) => void;
|
||||
theme: Theme;
|
||||
|
|
@ -146,22 +146,22 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
if (!isActive && channelId) {
|
||||
this.props.resetUnreadMessageCount(channelId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onIndicatorBarVisible = (indicatorVisible: boolean) => {
|
||||
this.indicatorBarVisible = indicatorVisible;
|
||||
this.animateButton();
|
||||
}
|
||||
};
|
||||
|
||||
onCurrentCallBarVisible = (currentCallVisible: boolean) => {
|
||||
this.currentCallBarVisible = currentCallVisible;
|
||||
this.animateButton();
|
||||
}
|
||||
};
|
||||
|
||||
onJoinCallBarVisible = (joinCallVisible: boolean) => {
|
||||
this.joinCallBarVisible = joinCallVisible;
|
||||
this.animateButton();
|
||||
}
|
||||
};
|
||||
|
||||
animateButton = () => {
|
||||
if (this.buttonVisible) {
|
||||
|
|
@ -171,7 +171,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
useNativeDriver: true,
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
reset = () => {
|
||||
if (this.autoCancelTimer) {
|
||||
|
|
@ -184,14 +184,14 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
this.pressed = false;
|
||||
this.canceled = false;
|
||||
this.disableViewableItems = false;
|
||||
}
|
||||
};
|
||||
|
||||
show = () => {
|
||||
if (!this.buttonVisible && this.state.moreText && !this.props.deepLinkURL && !this.canceled && this.props.unreadCount > 0) {
|
||||
this.buttonVisible = true;
|
||||
this.animateButton();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getBarsFactor = () => {
|
||||
return Math.abs((
|
||||
|
|
@ -199,7 +199,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
(this.joinCallBarVisible ? 0 : JOIN_CALL_BAR_HEIGHT) +
|
||||
(this.currentCallBarVisible ? 0 : CURRENT_CALL_BAR_HEIGHT)
|
||||
) / (HIDDEN_TOP - SHOWN_TOP));
|
||||
}
|
||||
};
|
||||
|
||||
hide = () => {
|
||||
if (this.buttonVisible) {
|
||||
|
|
@ -210,7 +210,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
useNativeDriver: true,
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cancel = (force = false) => {
|
||||
if (!force && (this.indicatorBarVisible || this.props.loadingPosts)) {
|
||||
|
|
@ -228,7 +228,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
this.canceled = true;
|
||||
this.disableViewableItems = true;
|
||||
this.hide();
|
||||
}
|
||||
};
|
||||
|
||||
uncancel = () => {
|
||||
if (this.autoCancelTimer) {
|
||||
|
|
@ -237,7 +237,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
}
|
||||
this.canceled = false;
|
||||
this.disableViewableItems = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMoreMessagesPress = () => {
|
||||
if (this.pressed) {
|
||||
|
|
@ -249,7 +249,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
const {newMessageLineIndex, scrollToIndex} = this.props;
|
||||
this.pressed = true;
|
||||
scrollToIndex(newMessageLineIndex, true);
|
||||
}
|
||||
};
|
||||
|
||||
onViewableItemsChanged = (viewableItems: ViewToken[]) => {
|
||||
this.viewableItems = viewableItems;
|
||||
|
|
@ -295,7 +295,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
readCount = 0;
|
||||
this.showMoreText(readCount);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
showMoreText = (readCount: number) => {
|
||||
const moreCount = this.props.unreadCount - readCount;
|
||||
|
|
@ -304,7 +304,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
const moreText = this.moreText(moreCount);
|
||||
this.setState({moreText}, this.show);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getReadCount = (lastViewableIndex: number) => {
|
||||
const {postIds} = this.props;
|
||||
|
|
@ -313,7 +313,7 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
const readCount = messageCount(viewedPostIds);
|
||||
|
||||
return readCount;
|
||||
}
|
||||
};
|
||||
|
||||
moreText = (count: number) => {
|
||||
const {unreadCount} = this.props;
|
||||
|
|
@ -324,12 +324,12 @@ export default class MoreMessageButton extends React.PureComponent<MoreMessagesB
|
|||
id: t('mobile.more_messages_button.text'),
|
||||
defaultMessage: '{count} {isInitialMessage, select, true {new} other {more new}} {count, plural, one {message} other {messages}}',
|
||||
}, {isInitialMessage, count});
|
||||
}
|
||||
};
|
||||
|
||||
onScrollEndIndex = (endIndex: number) => {
|
||||
this.pressed = false;
|
||||
this.endIndex = endIndex;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {theme, loadingPosts, testID} = this.props;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ const Body = ({
|
|||
const isReplyPost = Boolean(post.root_id && (!isPostEphemeral(post) || post.state === Posts.POST_DELETED) && location !== THREAD);
|
||||
const hasContent = (post.metadata?.embeds?.length || (appsEnabled && post.props?.app_bindings?.length)) || post.props?.attachments?.length;
|
||||
|
||||
const replyBarStyle = useCallback((): StyleProp<ViewStyle>[]|undefined => {
|
||||
const replyBarStyle = useCallback((): Array<StyleProp<ViewStyle>>|undefined => {
|
||||
if (!isReplyPost) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ type Props = {
|
|||
theme: Theme;
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme:Theme) => {
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
return {
|
||||
container: {
|
||||
borderBottomColor: changeOpacity(theme.centerChannelColor, 0.15),
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ const MenuBinding = ({binding, doAppCall, intl, post, postEphemeralCallResponseF
|
|||
}
|
||||
}, [theme]);
|
||||
|
||||
const options = binding.bindings?.map<PostActionOption>((b:AppBinding) => {
|
||||
const options = binding.bindings?.map<PostActionOption>((b: AppBinding) => {
|
||||
return {text: b.label, value: b.location || ''};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ import {makeStyleSheetFromTheme} from '@utils/theme';
|
|||
|
||||
type Props = {
|
||||
baseTextStyle: StyleProp<TextStyle>;
|
||||
blockStyles?: StyleProp<ViewStyle>[];
|
||||
blockStyles?: Array<StyleProp<ViewStyle>>;
|
||||
fields: MessageAttachmentField[];
|
||||
metadata?: PostMetadata;
|
||||
textStyles?: StyleProp<TextStyle>[];
|
||||
textStyles?: Array<StyleProp<TextStyle>>;
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import {PostMetadata} from '@mm-redux/types/posts';
|
|||
|
||||
type Props = {
|
||||
baseTextStyle: StyleProp<TextStyle>;
|
||||
blockStyles?: StyleProp<ViewStyle>[];
|
||||
blockStyles?: Array<StyleProp<ViewStyle>>;
|
||||
metadata?: PostMetadata;
|
||||
textStyles?: StyleProp<TextStyle>[];
|
||||
textStyles?: Array<StyleProp<TextStyle>>;
|
||||
value?: string;
|
||||
}
|
||||
export default function AttachmentPreText(props: Props) {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ import {Theme} from '@mm-redux/types/theme';
|
|||
|
||||
type Props = {
|
||||
baseTextStyle: StyleProp<TextStyle>;
|
||||
blockStyles?: StyleProp<ViewStyle>[];
|
||||
blockStyles?: Array<StyleProp<ViewStyle>>;
|
||||
hasThumbnail?: boolean;
|
||||
metadata?: PostMetadata;
|
||||
textStyles?: StyleProp<TextStyle>[];
|
||||
textStyles?: Array<StyleProp<TextStyle>>;
|
||||
theme: Theme;
|
||||
value?: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ type PostListProps = {
|
|||
}
|
||||
|
||||
type ViewableItemsChanged = {
|
||||
viewableItems: Array<ViewToken>;
|
||||
changed: Array<ViewToken>;
|
||||
viewableItems: ViewToken[];
|
||||
changed: ViewToken[];
|
||||
}
|
||||
|
||||
type onScrollEndIndexListenerEvent = (endIndex: number) => void;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export default class ProgressiveImage extends PureComponent {
|
|||
this.setState({
|
||||
showHighResImage: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onLoadImageEnd = () => {
|
||||
Animated.timing(this.state.intensity, {
|
||||
|
|
@ -63,7 +63,7 @@ export default class ProgressiveImage extends PureComponent {
|
|||
toValue: 100,
|
||||
useNativeDriver: true,
|
||||
}).start();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export default class ReactionButton extends PureComponent {
|
|||
emoji: PropTypes.string.isRequired,
|
||||
iconSize: PropTypes.number,
|
||||
containerSize: PropTypes.number,
|
||||
}
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
iconSize: LARGE_ICON_SIZE,
|
||||
|
|
@ -42,7 +42,7 @@ export default class ReactionButton extends PureComponent {
|
|||
this.setState({isSelected: true}, () => {
|
||||
this.props.addReaction(this.props.emoji);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ type RetriableFastImageState = {
|
|||
export default class RetriableFastImage extends PureComponent<RetriableFastImageProps, RetriableFastImageState> {
|
||||
state = {
|
||||
retry: 0,
|
||||
}
|
||||
};
|
||||
|
||||
onError = () => {
|
||||
const retry = this.state.retry + 1;
|
||||
|
|
@ -27,7 +27,7 @@ export default class RetriableFastImage extends PureComponent<RetriableFastImage
|
|||
}
|
||||
|
||||
this.setState({retry});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ export default class Root extends PureComponent {
|
|||
|
||||
setProviderRef = (ref) => {
|
||||
this.providerRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
handleNoTeams = () => {
|
||||
if (!this.providerRef) {
|
||||
|
|
@ -61,7 +61,7 @@ export default class Root extends PureComponent {
|
|||
return;
|
||||
}
|
||||
this.navigateToTeamsPage('ErrorTeamsList', true);
|
||||
}
|
||||
};
|
||||
|
||||
navigateToTeamsPage = (screen, error = false) => {
|
||||
const {currentUrl, theme} = this.props;
|
||||
|
|
@ -98,7 +98,7 @@ export default class Root extends PureComponent {
|
|||
}
|
||||
|
||||
resetToTeams(screen, title, passProps, options);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const locale = getLocaleFromLanguage(this.props.locale);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import type {Theme} from '@mm-redux/types/theme';
|
|||
|
||||
type SafeAreaProps = {
|
||||
backgroundColor?: string;
|
||||
children: Array<React.ReactChild> | React.ReactChild;
|
||||
children: React.ReactChild[] | React.ReactChild;
|
||||
excludeHeader?: boolean;
|
||||
excludeFooter?: boolean;
|
||||
excludeLeft?: boolean;
|
||||
|
|
|
|||
|
|
@ -98,11 +98,11 @@ export default class Search extends PureComponent {
|
|||
|
||||
setSearchContainerRef = (ref) => {
|
||||
this.searchContainerRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
setInputKeywordRef = (ref) => {
|
||||
this.inputKeywordRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
blur = () => {
|
||||
this.inputKeywordRef.blur();
|
||||
|
|
@ -188,7 +188,7 @@ export default class Search extends PureComponent {
|
|||
),
|
||||
]).start(resolve);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
collapseAnimation = () => {
|
||||
return new Promise((resolve) => {
|
||||
|
|
@ -209,7 +209,7 @@ export default class Search extends PureComponent {
|
|||
),
|
||||
]).start(resolve);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {testID, backgroundColor, inputHeight, inputStyle, placeholderTextColor, tintColorSearch, cancelButtonStyle, tintColorDelete, titleCancelColor, searchBarRightMargin, containerHeight} = this.props;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export default class ChannelsList extends PureComponent {
|
|||
|
||||
setSearchBarRef = (ref) => {
|
||||
this.searchBarRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
cancelSearch = () => {
|
||||
if (this.searchBarRef) {
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ class FilteredList extends Component {
|
|||
});
|
||||
|
||||
return this.filterChannels([...favoriteDms, ...dms, ...groupChannels], term).sort(sortChannelsByDisplayName.bind(null, props.intl.locale));
|
||||
}
|
||||
};
|
||||
|
||||
buildMembersForSearch = (props, term) => {
|
||||
const {channels, currentUserId, teammateNameDisplay, profiles, teamProfiles, pastDirectMessages, restrictDms} = props;
|
||||
|
|
@ -266,7 +266,7 @@ class FilteredList extends Component {
|
|||
const fakeDms = this.filterChannels([...members], term);
|
||||
|
||||
return [...fakeDms].sort(sortChannelsByDisplayName.bind(null, props.intl.locale));
|
||||
}
|
||||
};
|
||||
|
||||
buildChannelsForSearch = (props, term) => {
|
||||
const {
|
||||
|
|
@ -281,7 +281,7 @@ class FilteredList extends Component {
|
|||
|
||||
return this.filterChannels([...favorites, ...publicChannels, ...privateChannels], term).
|
||||
sort(sortChannelsByDisplayName.bind(null, props.intl.locale));
|
||||
}
|
||||
};
|
||||
|
||||
buildArchivedForSearch = (props, term) => {
|
||||
const {currentChannel, archivedChannels} = props;
|
||||
|
|
@ -294,7 +294,7 @@ class FilteredList extends Component {
|
|||
|
||||
return acc;
|
||||
}, []), term);
|
||||
}
|
||||
};
|
||||
|
||||
buildOtherMembersForSearch = (props, term) => {
|
||||
const {otherChannels} = props;
|
||||
|
|
@ -307,7 +307,7 @@ class FilteredList extends Component {
|
|||
});
|
||||
|
||||
return this.filterChannels(notMemberOf, term);
|
||||
}
|
||||
};
|
||||
|
||||
buildSectionsForSearch = (props, term) => {
|
||||
const sections = [];
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ export default class List extends PureComponent {
|
|||
|
||||
setListRef = (ref) => {
|
||||
this.listRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
getSectionConfigByType = (props, sectionType) => {
|
||||
const {canCreatePrivateChannels, canJoinPublicChannels} = props;
|
||||
|
|
@ -463,7 +463,7 @@ export default class List extends PureComponent {
|
|||
{header}
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
buildCategorySections = () => {
|
||||
const categoriesBySection = [];
|
||||
|
|
@ -496,7 +496,7 @@ export default class List extends PureComponent {
|
|||
}
|
||||
|
||||
return categoriesBySection;
|
||||
}
|
||||
};
|
||||
|
||||
scrollToTop = () => {
|
||||
//eslint-disable-next-line no-underscore-dangle
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export default class DrawerSwiper extends Component {
|
|||
if (this.swiperRef?.current) {
|
||||
this.swiperRef.current.scrollToInitial();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
swiperPageSelected = (index) => {
|
||||
this.props.onPageSelected(index);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ export default class MainSidebarAndroid extends MainSidebarBase {
|
|||
|
||||
handleSidebarDidOpen = () => {
|
||||
this.setState({opened: true});
|
||||
}
|
||||
};
|
||||
|
||||
onPageSelected = (index) => {
|
||||
this.swiperIndex = index;
|
||||
|
|
@ -69,7 +69,7 @@ export default class MainSidebarAndroid extends MainSidebarBase {
|
|||
|
||||
setProviderRef = (ref) => {
|
||||
this.providerRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const locale = this.props.locale;
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ export default class MainSidebarBase extends Component {
|
|||
const {setCategoryCollapsed} = this.props.actions;
|
||||
|
||||
setCategoryCollapsed(categoryId, collapse);
|
||||
}
|
||||
};
|
||||
|
||||
selectChannel = (channel, currentChannelId, closeDrawer = true) => {
|
||||
const {handleSelectChannel, handleNotViewingGlobalThreadsScreen} = this.props.actions;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export default class SettingsDrawerAndroid extends SettingsSidebarBase {
|
|||
goToCustomStatus = preventDoubleTap(() => {
|
||||
const {intl} = this.providerRef.getChildContext();
|
||||
this.goToCustomStatusScreen(intl);
|
||||
})
|
||||
});
|
||||
|
||||
renderNavigationView = () => {
|
||||
const {theme} = this.props;
|
||||
|
|
@ -65,7 +65,7 @@ export default class SettingsDrawerAndroid extends SettingsSidebarBase {
|
|||
|
||||
setProviderRef = (ref) => {
|
||||
this.providerRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const locale = this.props.locale;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ export default class SettingsDrawer extends SettingsSidebarBase {
|
|||
goToCustomStatus = preventDoubleTap(() => {
|
||||
const {intl} = this.context;
|
||||
this.goToCustomStatusScreen(intl);
|
||||
})
|
||||
});
|
||||
|
||||
renderNavigationView = () => {
|
||||
const {theme} = this.props;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ export default class SettingsSidebarBase extends PureComponent {
|
|||
this.setState({
|
||||
showRetryMessage: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleCustomStatusChange = (prevCustomStatus, customStatus) => {
|
||||
const isStatusSet = Boolean(customStatus?.emoji);
|
||||
|
|
@ -87,7 +87,7 @@ export default class SettingsSidebarBase extends PureComponent {
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
confirmResetBase = (status, intl) => {
|
||||
confirmOutOfOfficeDisabled(intl, status, this.updateStatus);
|
||||
|
|
@ -169,7 +169,7 @@ export default class SettingsSidebarBase extends PureComponent {
|
|||
goToCustomStatusScreen = (intl) => {
|
||||
this.closeSettingsSidebar();
|
||||
showModal('CustomStatus', intl.formatMessage({id: 'mobile.routes.custom_status', defaultMessage: 'Set a Status'}));
|
||||
}
|
||||
};
|
||||
|
||||
logout = preventDoubleTap(() => {
|
||||
const {logout} = this.props.actions;
|
||||
|
|
@ -239,7 +239,7 @@ export default class SettingsSidebarBase extends PureComponent {
|
|||
if (error) {
|
||||
this.setState({showStatus: true, showRetryMessage: true});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
renderCustomStatus = () => {
|
||||
const {isCustomStatusEnabled, customStatus, theme, isCustomStatusExpired, isCustomStatusExpirySupported} = this.props;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ export default class TextInputWithLocalizedPlaceholder extends PureComponent {
|
|||
|
||||
setInputRef = (ref) => {
|
||||
this.inputRef = ref;
|
||||
}
|
||||
};
|
||||
|
||||
blur = () => {
|
||||
this.inputRef.blur();
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export default class RadioSetting extends PureComponent {
|
|||
const {onChange, id} = this.props;
|
||||
onChange(id, item);
|
||||
this.setState({value: item});
|
||||
}
|
||||
};
|
||||
|
||||
renderCheckMark = (value, style) => {
|
||||
if (value === this.state.value) {
|
||||
|
|
@ -44,7 +44,7 @@ export default class RadioSetting extends PureComponent {
|
|||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
renderRowSeparator = (idx, separatorStyle) => {
|
||||
const {options} = this.props;
|
||||
|
|
@ -52,7 +52,7 @@ export default class RadioSetting extends PureComponent {
|
|||
return null;
|
||||
}
|
||||
return <View style={separatorStyle}/>;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {StyleProp, TextStyle, ViewStyle} from 'react-native';
|
|||
|
||||
interface CustomPropTypes {
|
||||
Children: ReactNode | ReactNodeArray;
|
||||
Style: object | number | StyleProp<TextStyle> | StyleProp<TextStyle>[] | StyleProp<ViewStyle> | StyleProp<ViewStyle>[];
|
||||
Style: object | number | StyleProp<TextStyle> | Array<StyleProp<TextStyle>> | StyleProp<ViewStyle> | Array<StyleProp<ViewStyle>>;
|
||||
}
|
||||
|
||||
export default CustomPropTypes;
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ class EMMProvider {
|
|||
{cancelable: false, onDismiss: resolve},
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default new EMMProvider();
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ class GlobalEventHandler {
|
|||
// clear error
|
||||
return e;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
serverUpgradeNeeded = async () => {
|
||||
const {dispatch} = Store.redux;
|
||||
|
|
@ -322,12 +322,12 @@ class GlobalEventHandler {
|
|||
this.pushNotificationListener = true;
|
||||
EventEmitter.on(ViewTypes.NOTIFICATION_IN_APP, this.handleInAppNotification);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
turnOffInAppNotificationHandling = () => {
|
||||
this.pushNotificationListener = false;
|
||||
EventEmitter.off(ViewTypes.NOTIFICATION_IN_APP, this.handleInAppNotification);
|
||||
}
|
||||
};
|
||||
|
||||
handleInAppNotification = (notification) => {
|
||||
const {payload} = notification;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class PushNotifications {
|
|||
return AndroidNotificationPreferences.getDeliveredNotifications();
|
||||
}
|
||||
return Notifications.ios.getDeliveredNotifications() as Promise<NotificationWithChannel[]>;
|
||||
}
|
||||
};
|
||||
|
||||
cancelAllLocalNotifications() {
|
||||
Notifications.cancelAllLocalNotifications();
|
||||
|
|
@ -132,7 +132,7 @@ class PushNotifications {
|
|||
} else {
|
||||
Notifications.ios.removeDeliveredNotifications(notificationIds);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setBadgeCountByMentions = (initialBadge = 0) => {
|
||||
let badgeCount = initialBadge;
|
||||
|
|
@ -148,7 +148,7 @@ class PushNotifications {
|
|||
badgeCount = badgeCount <= 0 ? 0 : badgeCount;
|
||||
Notifications.ios.setBadgeCount(badgeCount);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
createReplyCategory = () => {
|
||||
const {getState} = Store.redux!;
|
||||
|
|
@ -164,7 +164,7 @@ class PushNotifications {
|
|||
};
|
||||
const replyAction = new NotificationAction(REPLY_ACTION, 'background', replyTitle, true, replyTextInput);
|
||||
return new NotificationCategory(CATEGORY, [replyAction]);
|
||||
}
|
||||
};
|
||||
|
||||
getInitialNotification = async () => {
|
||||
const notification: NotificationWithData | undefined = await Notifications.getInitialNotification();
|
||||
|
|
@ -183,7 +183,7 @@ class PushNotifications {
|
|||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleNotification = (notification: NotificationWithData, isInitialNotification = false) => {
|
||||
const {payload, foreground, userInteraction} = notification;
|
||||
|
|
@ -231,17 +231,17 @@ class PushNotifications {
|
|||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
localNotification = (notification: Notification) => {
|
||||
Notifications.postLocalNotification(notification);
|
||||
}
|
||||
};
|
||||
|
||||
onNotificationOpened = (notification: NotificationWithData, completion: () => void) => {
|
||||
notification.userInteraction = true;
|
||||
this.handleNotification(notification);
|
||||
completion();
|
||||
}
|
||||
};
|
||||
|
||||
onNotificationReceivedBackground = (notification: NotificationWithData, completion: (response: NotificationBackgroundFetchResult) => void) => {
|
||||
this.handleNotification(notification);
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ export function markGroupChannelOpen(channelId: string): ActionFunc {
|
|||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const {currentUserId} = getState().entities.users;
|
||||
|
||||
const preferences: Array<PreferenceType> = [
|
||||
const preferences: PreferenceType[] = [
|
||||
{user_id: currentUserId, category: Preferences.CATEGORY_GROUP_CHANNEL_SHOW, name: channelId, value: 'true'},
|
||||
{user_id: currentUserId, category: Preferences.CATEGORY_CHANNEL_OPEN_TIME, name: channelId, value: new Date().getTime().toString()},
|
||||
];
|
||||
|
|
@ -168,7 +168,7 @@ export function markGroupChannelOpen(channelId: string): ActionFunc {
|
|||
};
|
||||
}
|
||||
|
||||
export function createGroupChannel(userIds: Array<string>): ActionFunc {
|
||||
export function createGroupChannel(userIds: string[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
dispatch({type: ChannelTypes.CREATE_CHANNEL_REQUEST, data: null});
|
||||
|
||||
|
|
@ -1357,7 +1357,7 @@ export function markChannelAsRead(channelId: string, prevChannelId?: string, upd
|
|||
|
||||
// Increments the number of posts in the channel by 1 and marks it as unread if necessary
|
||||
|
||||
export function markChannelAsUnread(teamId: string, channelId: string, mentions: Array<string>): ActionFunc {
|
||||
export function markChannelAsUnread(teamId: string, channelId: string, mentions: string[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const state = getState();
|
||||
const {myMembers} = state.entities.channels;
|
||||
|
|
@ -1397,7 +1397,7 @@ export function markChannelAsUnread(teamId: string, channelId: string, mentions:
|
|||
};
|
||||
}
|
||||
|
||||
export function getChannelMembersByIds(channelId: string, userIds: Array<string>) {
|
||||
export function getChannelMembersByIds(channelId: string, userIds: string[]) {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getChannelMembersByIds,
|
||||
onSuccess: ChannelTypes.RECEIVED_CHANNEL_MEMBERS,
|
||||
|
|
|
|||
|
|
@ -62,13 +62,13 @@ export function getCustomEmojiByName(name: string): ActionFunc {
|
|||
};
|
||||
}
|
||||
|
||||
export function getCustomEmojisByName(names: Array<string>): ActionFunc {
|
||||
export function getCustomEmojisByName(names: string[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
if (!names || names.length === 0) {
|
||||
return {data: true};
|
||||
}
|
||||
|
||||
const promises: Promise<ActionResult|ActionResult[]>[] = [];
|
||||
const promises: Array<Promise<ActionResult|ActionResult[]>> = [];
|
||||
names.forEach((name) => promises.push(dispatch(getCustomEmojiByName(name))));
|
||||
|
||||
await Promise.all(promises);
|
||||
|
|
@ -122,7 +122,7 @@ export function getCustomEmojis(
|
|||
};
|
||||
}
|
||||
|
||||
export function loadProfilesForCustomEmojis(emojis: Array<CustomEmoji>): ActionFunc {
|
||||
export function loadProfilesForCustomEmojis(emojis: CustomEmoji[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const usersToLoad: Dictionary<boolean> = {};
|
||||
emojis.forEach((emoji: CustomEmoji) => {
|
||||
|
|
|
|||
|
|
@ -74,9 +74,9 @@ export function bindClientFunc({
|
|||
}: {
|
||||
clientFunc: (...args: any[]) => Promise<any>;
|
||||
onRequest?: ActionType;
|
||||
onSuccess?: ActionType | Array<ActionType>;
|
||||
onSuccess?: ActionType | ActionType[];
|
||||
onFailure?: ActionType;
|
||||
params?: Array<any>;
|
||||
params?: any[];
|
||||
}): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
if (onRequest) {
|
||||
|
|
@ -112,7 +112,7 @@ export function bindClientFunc({
|
|||
|
||||
export function debounce(func: (...args: any) => unknown, wait: number, immediate?: boolean, cb?: () => unknown) {
|
||||
let timeout: NodeJS.Timeout|null;
|
||||
return function fx(...args: Array<any>) {
|
||||
return function fx(...args: any[]) {
|
||||
const runLater = () => {
|
||||
timeout = null;
|
||||
if (!immediate) {
|
||||
|
|
@ -136,7 +136,7 @@ export function debounce(func: (...args: any) => unknown, wait: number, immediat
|
|||
};
|
||||
}
|
||||
|
||||
export async function notVisibleUsersActions(state: GlobalState): Promise<Array<GenericAction>> {
|
||||
export async function notVisibleUsersActions(state: GlobalState): Promise<GenericAction[]> {
|
||||
let knownUsers: Set<string>;
|
||||
try {
|
||||
const fetchResult = await Client4.getKnownUsers();
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ export function receivedPosts(posts: CombinedPostList) {
|
|||
}
|
||||
|
||||
// receivedPostsAfter should be dispatched when receiving an ordered list of posts that come before a given post.
|
||||
export function receivedPostsAfter(posts: Array<Post>, channelId: string, afterPostId: string, recent = false) {
|
||||
export function receivedPostsAfter(posts: Post[], channelId: string, afterPostId: string, recent = false) {
|
||||
return {
|
||||
type: PostTypes.RECEIVED_POSTS_AFTER,
|
||||
channelId,
|
||||
|
|
@ -82,7 +82,7 @@ export function receivedPostsAfter(posts: Array<Post>, channelId: string, afterP
|
|||
}
|
||||
|
||||
// receivedPostsBefore should be dispatched when receiving an ordered list of posts that come after a given post.
|
||||
export function receivedPostsBefore(posts: Array<Post>, channelId: string, beforePostId: string, oldest = false) {
|
||||
export function receivedPostsBefore(posts: Post[], channelId: string, beforePostId: string, oldest = false) {
|
||||
return {
|
||||
type: PostTypes.RECEIVED_POSTS_BEFORE,
|
||||
channelId,
|
||||
|
|
@ -95,7 +95,7 @@ export function receivedPostsBefore(posts: Array<Post>, channelId: string, befor
|
|||
// receivedPostsSince should be dispatched when receiving a list of posts that have been updated since a certain time.
|
||||
// Due to how the API endpoint works, some of these posts will be ordered, but others will not, so this needs special
|
||||
// handling from the reducers.
|
||||
export function receivedPostsSince(posts: Array<Post>, channelId: string) {
|
||||
export function receivedPostsSince(posts: Post[], channelId: string) {
|
||||
return {
|
||||
type: PostTypes.RECEIVED_POSTS_SINCE,
|
||||
channelId,
|
||||
|
|
@ -116,7 +116,7 @@ export function receivedPostsInChannel(posts: CombinedPostList, channelId: strin
|
|||
}
|
||||
|
||||
// receivedPostsInThread should be dispatched when receiving a list of unordered posts in a thread.
|
||||
export function receivedPostsInThread(posts: Array<Post>, rootId: string) {
|
||||
export function receivedPostsInThread(posts: Post[], rootId: string) {
|
||||
return {
|
||||
type: PostTypes.RECEIVED_POSTS_IN_THREAD,
|
||||
data: posts,
|
||||
|
|
@ -175,7 +175,7 @@ export function createPost(post: Post, files: any[] = []) {
|
|||
const currentUserId = state.entities.users.currentUserId;
|
||||
const timestamp = Date.now();
|
||||
const pendingPostId = post.pending_post_id || `${currentUserId}:${timestamp}`;
|
||||
let actions: Array<Action> = [];
|
||||
let actions: Action[] = [];
|
||||
|
||||
if (Selectors.isPostIdSending(state, pendingPostId)) {
|
||||
return {data: true};
|
||||
|
|
@ -843,8 +843,8 @@ export function getPostsAfter(channelId: string, postId: string, page = 0, perPa
|
|||
};
|
||||
}
|
||||
export type CombinedPostList = {
|
||||
posts: Array<Post>;
|
||||
order: Array<string>;
|
||||
posts: Post[];
|
||||
order: string[];
|
||||
next_post_id: string;
|
||||
prev_post_id: string;
|
||||
}
|
||||
|
|
@ -897,14 +897,14 @@ export function getPostsAround(channelId: string, postId: string, perPage = Post
|
|||
|
||||
// getThreadsForPosts is intended for an array of posts that have been batched
|
||||
// (see the actions/websocket_actions/handleNewPostEvents function in the webapp)
|
||||
export function getThreadsForPosts(posts: Array<Post>, fetchThreads = true) {
|
||||
export function getThreadsForPosts(posts: Post[], fetchThreads = true) {
|
||||
return (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
if (!Array.isArray(posts) || !posts.length) {
|
||||
return {data: true};
|
||||
}
|
||||
|
||||
const state = getState();
|
||||
const promises: Promise<ActionResult>[] = [];
|
||||
const promises: Array<Promise<ActionResult>> = [];
|
||||
|
||||
posts.forEach((post) => {
|
||||
if (!post.root_id) {
|
||||
|
|
@ -922,7 +922,7 @@ export function getThreadsForPosts(posts: Array<Post>, fetchThreads = true) {
|
|||
}
|
||||
|
||||
// Note that getProfilesAndStatusesForPosts can take either an array of posts or a map of ids to posts
|
||||
export function getProfilesAndStatusesForPosts(postsArrayOrMap: Array<Post>|Map<string, Post>, dispatch: DispatchFunc, getState: GetStateFunc) {
|
||||
export function getProfilesAndStatusesForPosts(postsArrayOrMap: Post[]|Map<string, Post>, dispatch: DispatchFunc, getState: GetStateFunc) {
|
||||
if (!postsArrayOrMap) {
|
||||
// Some API methods return {error} for no results
|
||||
return Promise.resolve();
|
||||
|
|
@ -983,7 +983,7 @@ export function getProfilesAndStatusesForPosts(postsArrayOrMap: Array<Post>|Map<
|
|||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
export function getNeededAtMentionedUsernames(state: GlobalState, posts: Array<Post>): Set<string> {
|
||||
export function getNeededAtMentionedUsernames(state: GlobalState, posts: Post[]): Set<string> {
|
||||
let usersByUsername: Dictionary<UserProfile>; // Populate this lazily since it's relatively expensive
|
||||
|
||||
const usernamesToLoad = new Set<string>();
|
||||
|
|
@ -1021,7 +1021,7 @@ export function getNeededAtMentionedUsernames(state: GlobalState, posts: Array<P
|
|||
return usernamesToLoad;
|
||||
}
|
||||
|
||||
function buildPostAttachmentText(attachments: Array<any>) {
|
||||
function buildPostAttachmentText(attachments: any[]) {
|
||||
let attachmentText = '';
|
||||
|
||||
attachments.forEach((a) => {
|
||||
|
|
@ -1043,7 +1043,7 @@ function buildPostAttachmentText(attachments: Array<any>) {
|
|||
return attachmentText;
|
||||
}
|
||||
|
||||
export function getNeededCustomEmojis(state: GlobalState, posts: Array<Post>): Set<string> {
|
||||
export function getNeededCustomEmojis(state: GlobalState, posts: Post[]): Set<string> {
|
||||
if (getConfig(state).EnableCustomEmoji !== 'true') {
|
||||
return new Set<string>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {getChannelAndMyMember, getMyChannelMember} from './channels';
|
|||
import {bindClientFunc} from './helpers';
|
||||
import {getProfilesByIds, getProfilesInChannel} from './users';
|
||||
|
||||
export function deletePreferences(userId: string, preferences: Array<PreferenceType>): ActionFunc {
|
||||
export function deletePreferences(userId: string, preferences: PreferenceType[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const state = getState();
|
||||
const myPreferences = getMyPreferencesSelector(state);
|
||||
|
|
@ -99,7 +99,7 @@ export function makeGroupMessageVisibleIfNecessary(channelId: string): ActionFun
|
|||
};
|
||||
}
|
||||
|
||||
export function savePreferences(userId: string, preferences: Array<PreferenceType>) {
|
||||
export function savePreferences(userId: string, preferences: PreferenceType[]) {
|
||||
return async (dispatch: DispatchFunc) => {
|
||||
try {
|
||||
// Optimistic action
|
||||
|
|
@ -139,10 +139,10 @@ export function saveTheme(teamId: string, theme: {}): ActionFunc {
|
|||
|
||||
export function deleteTeamSpecificThemes(): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const getCategory: (state: any, preferenceId: string) => Array<PreferenceType> = makeGetCategory();
|
||||
const getCategory: (state: any, preferenceId: string) => PreferenceType[] = makeGetCategory();
|
||||
|
||||
const state = getState();
|
||||
const themePreferences: Array<PreferenceType> = getCategory(state, Preferences.CATEGORY_THEME);
|
||||
const themePreferences: PreferenceType[] = getCategory(state, Preferences.CATEGORY_THEME);
|
||||
const currentUserId = getCurrentUserId(state);
|
||||
|
||||
const toDelete = themePreferences.filter((pref) => pref.name !== '');
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {getRoles} from '@mm-redux/selectors/entities/roles_helpers';
|
|||
import {DispatchFunc, GetStateFunc, ActionFunc} from '@mm-redux/types/actions';
|
||||
|
||||
import {bindClientFunc} from './helpers';
|
||||
export function getRolesByNames(rolesNames: Array<string>) {
|
||||
export function getRolesByNames(rolesNames: string[]) {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getRolesByNames,
|
||||
onSuccess: [RoleTypes.RECEIVED_ROLES, RoleTypes.ROLES_BY_NAMES_SUCCESS],
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export function getMissingChannelsFromPosts(posts: RelationOneToOne<Post, Post>)
|
|||
membersInChannel,
|
||||
myMembers,
|
||||
} = getState().entities.channels;
|
||||
const promises: Promise<ActionResult>[] = [];
|
||||
const promises: Array<Promise<ActionResult>> = [];
|
||||
Object.values(posts).forEach((post) => {
|
||||
const id = post.channel_id;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ async function getProfilesAndStatusesForMembers(userIds: string[], dispatch: Dis
|
|||
statusesToLoad.push(userId);
|
||||
}
|
||||
});
|
||||
const requests: Promise<ActionResult|ActionResult[]>[] = [];
|
||||
const requests: Array<Promise<ActionResult|ActionResult[]>> = [];
|
||||
|
||||
if (profilesToLoad.length) {
|
||||
requests.push(dispatch(getProfilesByIds(profilesToLoad)));
|
||||
|
|
@ -320,7 +320,7 @@ export function addUserToTeam(teamId: string, userId: string): ActionFunc {
|
|||
return {error};
|
||||
}
|
||||
|
||||
const actions: Array<Action> = [{
|
||||
const actions: Action[] = [{
|
||||
type: UserTypes.RECEIVED_PROFILE_IN_TEAM,
|
||||
data: {id: teamId, user_id: userId},
|
||||
}, {
|
||||
|
|
@ -335,7 +335,8 @@ export function addUserToTeam(teamId: string, userId: string): ActionFunc {
|
|||
const state = getState();
|
||||
const currentRoles = getRoles(state);
|
||||
const rolesToLoad = new Set<string>();
|
||||
for (const role of member.roles?.split(' ')) {
|
||||
const memberRoles = member.roles?.split(' ') || [];
|
||||
for (const role of memberRoles) {
|
||||
if (!currentRoles[role] && role.trim() !== '') {
|
||||
rolesToLoad.add(role);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export function getThreads(userId: string, teamId: string, before = '', after =
|
|||
});
|
||||
});
|
||||
|
||||
const getThreadsActions: Array<GenericAction> = [
|
||||
const getThreadsActions: GenericAction[] = [
|
||||
{
|
||||
type: ThreadTypes.RECEIVED_THREADS,
|
||||
data: {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ function completeLogin(data: UserProfile): ActionFunc {
|
|||
let teamMembers;
|
||||
|
||||
try {
|
||||
const membersRequest: Promise<Array<TeamMembership>> = Client4.getMyTeamMembers();
|
||||
const membersRequest: Promise<TeamMembership[]> = Client4.getMyTeamMembers();
|
||||
const unreadsRequest = Client4.getMyTeamUnreads();
|
||||
|
||||
teamMembers = await membersRequest;
|
||||
|
|
@ -209,7 +209,7 @@ export function getProfiles(page = 0, perPage: number = General.PROFILE_CHUNK_SI
|
|||
};
|
||||
}
|
||||
|
||||
export function getMissingProfilesByIds(userIds: Array<string>): ActionFunc {
|
||||
export function getMissingProfilesByIds(userIds: string[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const {profiles} = getState().entities.users;
|
||||
const missingIds: string[] = [];
|
||||
|
|
@ -228,7 +228,7 @@ export function getMissingProfilesByIds(userIds: Array<string>): ActionFunc {
|
|||
};
|
||||
}
|
||||
|
||||
export function getMissingProfilesByUsernames(usernames: Array<string>): ActionFunc {
|
||||
export function getMissingProfilesByUsernames(usernames: string[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const {profiles} = getState().entities.users;
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ export function getMissingProfilesByUsernames(usernames: Array<string>): ActionF
|
|||
};
|
||||
}
|
||||
|
||||
export function getProfilesByIds(userIds: Array<string>, options?: any): ActionFunc {
|
||||
export function getProfilesByIds(userIds: string[], options?: any): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const {currentUserId} = getState().entities.users;
|
||||
let profiles: UserProfile[];
|
||||
|
|
@ -273,7 +273,7 @@ export function getProfilesByIds(userIds: Array<string>, options?: any): ActionF
|
|||
};
|
||||
}
|
||||
|
||||
export function getProfilesByUsernames(usernames: Array<string>): ActionFunc {
|
||||
export function getProfilesByUsernames(usernames: string[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const {currentUserId} = getState().entities.users;
|
||||
let profiles;
|
||||
|
|
@ -410,7 +410,7 @@ export function getProfilesInChannel(channelId: string, page: number, perPage: n
|
|||
};
|
||||
}
|
||||
|
||||
export function getProfilesInGroupChannels(channelsIds: Array<string>): ActionFunc {
|
||||
export function getProfilesInGroupChannels(channelsIds: string[]): ActionFunc {
|
||||
return async (dispatch: DispatchFunc, getState: GetStateFunc) => {
|
||||
const {currentUserId} = getState().entities.users;
|
||||
let channelProfiles;
|
||||
|
|
@ -581,7 +581,7 @@ export function getUserByEmail(email: string): ActionFunc {
|
|||
// the array. Helps with performance because instead of making 75 different calls for
|
||||
// statuses, we are only making one call for 75 ids.
|
||||
// We could maybe clean it up somewhat by storing the array of ids in redux state possbily?
|
||||
let ids: Array<string> = [];
|
||||
let ids: string[] = [];
|
||||
const debouncedGetStatusesByIds = debounce(async (dispatch: DispatchFunc) => {
|
||||
dispatch(getStatusesByIds([...new Set(ids)]));
|
||||
}, 20, false, () => {
|
||||
|
|
@ -592,7 +592,7 @@ export function getStatusesByIdsBatchedDebounced(id: string) {
|
|||
return debouncedGetStatusesByIds;
|
||||
}
|
||||
|
||||
export function getStatusesByIds(userIds: Array<string>): ActionFunc {
|
||||
export function getStatusesByIds(userIds: string[]): ActionFunc {
|
||||
return bindClientFunc({
|
||||
clientFunc: Client4.getStatusesByIds,
|
||||
onSuccess: UserTypes.RECEIVED_STATUSES,
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ function channels(state: IDMappedObjects<Channel> = {}, action: GenericAction) {
|
|||
}
|
||||
case ChannelTypes.RECEIVED_MY_CHANNELS_WITH_MEMBERS: { // Used by the mobile app
|
||||
const nextState = {...state};
|
||||
const myChannels: Array<Channel> = action.data.channels;
|
||||
const myChannels: Channel[] = action.data.channels;
|
||||
let hasNewValues = false;
|
||||
|
||||
if (myChannels && myChannels.length) {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ function storeFilesForPost(state: Dictionary<FileInfo>, post: Post) {
|
|||
}, state);
|
||||
}
|
||||
|
||||
export function fileIdsByPostId(state: Dictionary<Array<string>> = {}, action: GenericAction) {
|
||||
export function fileIdsByPostId(state: Dictionary<string[]> = {}, action: GenericAction) {
|
||||
switch (action.type) {
|
||||
case FileTypes.RECEIVED_FILES_FOR_POST: {
|
||||
const {data, postId} = action;
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ function systemCommands(state: IDMappedObjects<Command> = {}, action: GenericAct
|
|||
}
|
||||
}
|
||||
|
||||
function commandAutocompleteSuggestions(state: Array<AutocompleteSuggestion> = [], action: GenericAction) {
|
||||
function commandAutocompleteSuggestions(state: AutocompleteSuggestion[] = [], action: GenericAction) {
|
||||
switch (action.type) {
|
||||
case IntegrationTypes.RECEIVED_COMMAND_SUGGESTIONS:
|
||||
return action.data;
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ function handlePostReceived(nextState: any, post: Post) {
|
|||
return nextState;
|
||||
}
|
||||
|
||||
export function handlePendingPosts(state: Array<string> = [], action: GenericAction) {
|
||||
export function handlePendingPosts(state: string[] = [], action: GenericAction) {
|
||||
switch (action.type) {
|
||||
case PostTypes.RECEIVED_NEW_POST: {
|
||||
const post = action.data;
|
||||
|
|
@ -297,7 +297,7 @@ export function handlePendingPosts(state: Array<string> = [], action: GenericAct
|
|||
}
|
||||
}
|
||||
|
||||
export function postsInChannel(state: Dictionary<Array<PostOrderBlock>> = {}, action: GenericAction, prevPosts: IDMappedObjects<Post>, nextPosts: Dictionary<Post>) {
|
||||
export function postsInChannel(state: Dictionary<PostOrderBlock[]> = {}, action: GenericAction, prevPosts: IDMappedObjects<Post>, nextPosts: Dictionary<Post>) {
|
||||
switch (action.type) {
|
||||
case PostTypes.RECEIVED_NEW_POST: {
|
||||
const post = action.data as Post;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue