forked from Ivasoft/mattermost-mobile
Compare commits
21 Commits
MM-50010-c
...
test1.0.4
| Author | SHA1 | Date | |
|---|---|---|---|
| d37bc4c14a | |||
| 2bb144042b | |||
| b960c2f036 | |||
| 2aa1265762 | |||
| 565c19ca64 | |||
| b4acbef5f5 | |||
| 0a766bfb65 | |||
| b7cc411c3b | |||
| 04b35959a3 | |||
| e639e69d46 | |||
|
|
07aa748cd7 | ||
|
|
01b5fc0f9e | ||
|
|
9b932c401a | ||
|
|
5ccf45622d | ||
|
|
279b601b2a | ||
|
|
049e763204 | ||
|
|
d6e7889afc | ||
|
|
46df588a6a | ||
|
|
a92574cdf3 | ||
|
|
fdd0bed294 | ||
|
|
72c5271598 |
31
.drone.yml
Normal file
31
.drone.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: permissions
|
||||
image: alpine/git
|
||||
commands:
|
||||
- chmod -R 777 .
|
||||
|
||||
- name: build
|
||||
image: cimg/android:2022.09.2-node
|
||||
environment:
|
||||
CIRCLECI: true
|
||||
NODE_OPTIONS: --max_old_space_size=12000
|
||||
NODE_ENV: production
|
||||
BABEL_ENV: production
|
||||
MATTERMOST_RELEASE_STORE_FILE: /root/mattermost.keystore
|
||||
MATTERMOST_RELEASE_KEY_ALIAS: mattermost-google-key
|
||||
MATTERMOST_RELEASE_PASSWORD: 123456
|
||||
commands:
|
||||
- 'npm run build:android'
|
||||
|
||||
- name: gitea_release
|
||||
image: plugins/gitea-release
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: drone_release
|
||||
base_url: https://git.ivasoft.cz
|
||||
files: '*.apk'
|
||||
when:
|
||||
event: tag
|
||||
@@ -110,7 +110,7 @@ android {
|
||||
applicationId "com.mattermost.rnbeta"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 460
|
||||
versionCode 461
|
||||
versionName "2.1.0"
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
@@ -6,7 +6,7 @@ import {Platform} from 'react-native';
|
||||
|
||||
import {WebsocketEvents} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getConfig} from '@queries/servers/system';
|
||||
import {getConfigValue} from '@queries/servers/system';
|
||||
import {hasReliableWebsocket} from '@utils/config';
|
||||
import {toMilliseconds} from '@utils/datetime';
|
||||
import {logError, logInfo, logWarning} from '@utils/log';
|
||||
@@ -79,8 +79,12 @@ export default class WebSocketClient {
|
||||
return;
|
||||
}
|
||||
|
||||
const config = await getConfig(database);
|
||||
const connectionUrl = (config.WebsocketURL || this.serverUrl) + '/api/v4/websocket';
|
||||
const [websocketUrl, version, reliableWebsocketConfig] = await Promise.all([
|
||||
getConfigValue(database, 'WebsocketURL'),
|
||||
getConfigValue(database, 'Version'),
|
||||
getConfigValue(database, 'EnableReliableWebSockets'),
|
||||
]);
|
||||
const connectionUrl = (websocketUrl || this.serverUrl) + '/api/v4/websocket';
|
||||
|
||||
if (this.connectingCallback) {
|
||||
this.connectingCallback();
|
||||
@@ -101,7 +105,7 @@ export default class WebSocketClient {
|
||||
|
||||
this.url = connectionUrl;
|
||||
|
||||
const reliableWebSockets = hasReliableWebsocket(config);
|
||||
const reliableWebSockets = hasReliableWebsocket(version, reliableWebsocketConfig);
|
||||
if (reliableWebSockets) {
|
||||
// Add connection id, and last_sequence_number to the query param.
|
||||
// We cannot also send it as part of the auth_challenge, because the session cookie is already sent with the request.
|
||||
@@ -129,6 +133,11 @@ export default class WebSocketClient {
|
||||
headers.Authorization = `Bearer ${this.token}`;
|
||||
}
|
||||
const {client} = await getOrCreateWebSocketClient(this.url, {headers, timeoutInterval: WEBSOCKET_TIMEOUT});
|
||||
|
||||
// Check again if the client is the same, to avoid race conditions
|
||||
if (this.conn === client) {
|
||||
return;
|
||||
}
|
||||
this.conn = client;
|
||||
} catch (error) {
|
||||
return;
|
||||
|
||||
@@ -14,7 +14,7 @@ import TeamList from './team_list';
|
||||
type Props = {
|
||||
iconPad?: boolean;
|
||||
canJoinOtherTeams: boolean;
|
||||
teamsCount: number;
|
||||
hasMoreThanOneTeam: boolean;
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
@@ -36,8 +36,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
};
|
||||
});
|
||||
|
||||
export default function TeamSidebar({iconPad, canJoinOtherTeams, teamsCount}: Props) {
|
||||
const initialWidth = teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0;
|
||||
export default function TeamSidebar({iconPad, canJoinOtherTeams, hasMoreThanOneTeam}: Props) {
|
||||
const initialWidth = hasMoreThanOneTeam ? TEAM_SIDEBAR_WIDTH : 0;
|
||||
const width = useSharedValue(initialWidth);
|
||||
const marginTop = useSharedValue(iconPad ? 44 : 0);
|
||||
const theme = useTheme();
|
||||
@@ -58,8 +58,8 @@ export default function TeamSidebar({iconPad, canJoinOtherTeams, teamsCount}: Pr
|
||||
}, [iconPad]);
|
||||
|
||||
useEffect(() => {
|
||||
width.value = teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0;
|
||||
}, [teamsCount]);
|
||||
width.value = hasMoreThanOneTeam ? TEAM_SIDEBAR_WIDTH : 0;
|
||||
}, [hasMoreThanOneTeam]);
|
||||
|
||||
return (
|
||||
<Animated.View style={[styles.container, transform]}>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import {of as of$} from 'rxjs';
|
||||
import {of as of$, Observable} from 'rxjs';
|
||||
import {switchMap, combineLatestWith, distinctUntilChanged} from 'rxjs/operators';
|
||||
|
||||
import {Preferences} from '@constants';
|
||||
@@ -19,6 +19,7 @@ import CategoryBody from './category_body';
|
||||
import type {WithDatabaseArgs} from '@typings/database/database';
|
||||
import type CategoryModel from '@typings/database/models/servers/category';
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type MyChannelModel from '@typings/database/models/servers/my_channel';
|
||||
import type PreferenceModel from '@typings/database/models/servers/preference';
|
||||
|
||||
type EnhanceProps = {
|
||||
@@ -30,8 +31,7 @@ type EnhanceProps = {
|
||||
|
||||
const withUserId = withObservables([], ({database}: WithDatabaseArgs) => ({currentUserId: observeCurrentUserId(database)}));
|
||||
|
||||
const observeCategoryChannels = (category: CategoryModel) => {
|
||||
const myChannels = category.myChannels.observeWithColumns(['last_post_at', 'is_unread']);
|
||||
const observeCategoryChannels = (category: CategoryModel, myChannels: Observable<MyChannelModel[]>) => {
|
||||
const channels = category.channels.observeWithColumns(['create_at', 'display_name']);
|
||||
const manualSort = category.categoryChannelsBySortOrder.observeWithColumns(['sort_order']);
|
||||
return myChannels.pipe(
|
||||
@@ -57,7 +57,8 @@ const observeCategoryChannels = (category: CategoryModel) => {
|
||||
};
|
||||
|
||||
const enhanced = withObservables([], ({category, currentUserId, database, isTablet, locale}: EnhanceProps) => {
|
||||
const channelsWithMyChannel = observeCategoryChannels(category);
|
||||
const categoryMyChannels = category.myChannels.observeWithColumns(['last_post_at', 'is_unread']);
|
||||
const channelsWithMyChannel = observeCategoryChannels(category, categoryMyChannels);
|
||||
const currentChannelId = isTablet ? observeCurrentChannelId(database) : of$('');
|
||||
const lastUnreadId = isTablet ? observeLastUnreadChannelId(database) : of$(undefined);
|
||||
|
||||
@@ -77,9 +78,9 @@ const enhanced = withObservables([], ({category, currentUserId, database, isTabl
|
||||
);
|
||||
}
|
||||
|
||||
const notifyPropsPerChannel = channelsWithMyChannel.pipe(
|
||||
const notifyPropsPerChannel = categoryMyChannels.pipe(
|
||||
// eslint-disable-next-line max-nested-callbacks
|
||||
switchMap((cwms) => observeNotifyPropsByChannels(database, cwms.map((c) => c.myChannel))),
|
||||
switchMap((mc) => observeNotifyPropsByChannels(database, mc)),
|
||||
);
|
||||
|
||||
const hiddenDmPrefs = queryPreferencesByCategoryAndName(database, Preferences.CATEGORIES.DIRECT_CHANNEL_SHOW, undefined, 'false').
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import {combineLatest, of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
import {distinctUntilChanged, switchMap} from 'rxjs/operators';
|
||||
|
||||
import {Permissions} from '@constants';
|
||||
import {observePermissionForTeam} from '@queries/servers/role';
|
||||
@@ -25,6 +25,7 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
|
||||
const canJoinChannels = combineLatest([currentUser, team]).pipe(
|
||||
switchMap(([u, t]) => observePermissionForTeam(database, t, u, Permissions.JOIN_PUBLIC_CHANNELS, true)),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
|
||||
const canCreatePublicChannels = combineLatest([currentUser, team]).pipe(
|
||||
@@ -37,6 +38,7 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
|
||||
const canCreateChannels = combineLatest([canCreatePublicChannels, canCreatePrivateChannels]).pipe(
|
||||
switchMap(([open, priv]) => of$(open || priv)),
|
||||
distinctUntilChanged(),
|
||||
);
|
||||
|
||||
const canAddUserToTeam = combineLatest([currentUser, team]).pipe(
|
||||
@@ -48,9 +50,11 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
canJoinChannels,
|
||||
canInvitePeople: combineLatest([enableOpenServer, canAddUserToTeam]).pipe(
|
||||
switchMap(([openServer, addUser]) => of$(openServer && addUser)),
|
||||
distinctUntilChanged(),
|
||||
),
|
||||
displayName: team.pipe(
|
||||
switchMap((t) => of$(t?.displayName)),
|
||||
distinctUntilChanged(),
|
||||
),
|
||||
pushProxyStatus: observePushVerificationStatus(database),
|
||||
};
|
||||
|
||||
@@ -33,8 +33,8 @@ describe('components/categories_list', () => {
|
||||
it('should render', () => {
|
||||
const wrapper = renderWithEverything(
|
||||
<CategoriesList
|
||||
teamsCount={1}
|
||||
channelsCount={1}
|
||||
moreThanOneTeam={false}
|
||||
hasChannels={true}
|
||||
/>,
|
||||
{database},
|
||||
);
|
||||
@@ -46,8 +46,8 @@ describe('components/categories_list', () => {
|
||||
const wrapper = renderWithEverything(
|
||||
<CategoriesList
|
||||
isCRTEnabled={true}
|
||||
teamsCount={1}
|
||||
channelsCount={1}
|
||||
moreThanOneTeam={false}
|
||||
hasChannels={true}
|
||||
/>,
|
||||
{database},
|
||||
);
|
||||
@@ -67,8 +67,8 @@ describe('components/categories_list', () => {
|
||||
jest.useFakeTimers();
|
||||
const wrapper = renderWithEverything(
|
||||
<CategoriesList
|
||||
teamsCount={0}
|
||||
channelsCount={1}
|
||||
moreThanOneTeam={false}
|
||||
hasChannels={true}
|
||||
/>,
|
||||
{database},
|
||||
);
|
||||
@@ -89,8 +89,8 @@ describe('components/categories_list', () => {
|
||||
jest.useFakeTimers();
|
||||
const wrapper = renderWithEverything(
|
||||
<CategoriesList
|
||||
teamsCount={1}
|
||||
channelsCount={0}
|
||||
moreThanOneTeam={true}
|
||||
hasChannels={false}
|
||||
/>,
|
||||
{database},
|
||||
);
|
||||
|
||||
@@ -27,28 +27,28 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
}));
|
||||
|
||||
type ChannelListProps = {
|
||||
channelsCount: number;
|
||||
hasChannels: boolean;
|
||||
iconPad?: boolean;
|
||||
isCRTEnabled?: boolean;
|
||||
teamsCount: number;
|
||||
moreThanOneTeam: boolean;
|
||||
};
|
||||
|
||||
const getTabletWidth = (teamsCount: number) => {
|
||||
return TABLET_SIDEBAR_WIDTH - (teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0);
|
||||
const getTabletWidth = (moreThanOneTeam: boolean) => {
|
||||
return TABLET_SIDEBAR_WIDTH - (moreThanOneTeam ? TEAM_SIDEBAR_WIDTH : 0);
|
||||
};
|
||||
|
||||
const CategoriesList = ({channelsCount, iconPad, isCRTEnabled, teamsCount}: ChannelListProps) => {
|
||||
const CategoriesList = ({hasChannels, iconPad, isCRTEnabled, moreThanOneTeam}: ChannelListProps) => {
|
||||
const theme = useTheme();
|
||||
const styles = getStyleSheet(theme);
|
||||
const {width} = useWindowDimensions();
|
||||
const isTablet = useIsTablet();
|
||||
const tabletWidth = useSharedValue(isTablet ? getTabletWidth(teamsCount) : 0);
|
||||
const tabletWidth = useSharedValue(isTablet ? getTabletWidth(moreThanOneTeam) : 0);
|
||||
|
||||
useEffect(() => {
|
||||
if (isTablet) {
|
||||
tabletWidth.value = getTabletWidth(teamsCount);
|
||||
tabletWidth.value = getTabletWidth(moreThanOneTeam);
|
||||
}
|
||||
}, [isTablet && teamsCount]);
|
||||
}, [isTablet && moreThanOneTeam]);
|
||||
|
||||
const tabletStyle = useAnimatedStyle(() => {
|
||||
if (!isTablet) {
|
||||
@@ -61,7 +61,7 @@ const CategoriesList = ({channelsCount, iconPad, isCRTEnabled, teamsCount}: Chan
|
||||
}, [isTablet, width]);
|
||||
|
||||
const content = useMemo(() => {
|
||||
if (channelsCount < 1) {
|
||||
if (!hasChannels) {
|
||||
return (<LoadChannelsError/>);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,10 @@ import Servers from './servers';
|
||||
import type {LaunchType} from '@typings/launch';
|
||||
|
||||
type ChannelProps = {
|
||||
channelsCount: number;
|
||||
hasChannels: boolean;
|
||||
isCRTEnabled: boolean;
|
||||
teamsCount: number;
|
||||
hasTeams: boolean;
|
||||
hasMoreThanOneTeam: boolean;
|
||||
isLicensed: boolean;
|
||||
showToS: boolean;
|
||||
launchType: LaunchType;
|
||||
@@ -126,10 +127,10 @@ const ChannelListScreen = (props: ChannelProps) => {
|
||||
}, [theme, insets.top]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.teamsCount) {
|
||||
if (!props.hasTeams) {
|
||||
resetToTeams();
|
||||
}
|
||||
}, [Boolean(props.teamsCount)]);
|
||||
}, [Boolean(props.hasTeams)]);
|
||||
|
||||
useEffect(() => {
|
||||
const back = BackHandler.addEventListener('hardwareBackPress', handleBackPress);
|
||||
@@ -176,13 +177,13 @@ const ChannelListScreen = (props: ChannelProps) => {
|
||||
>
|
||||
<TeamSidebar
|
||||
iconPad={canAddOtherServers}
|
||||
teamsCount={props.teamsCount}
|
||||
hasMoreThanOneTeam={props.hasMoreThanOneTeam}
|
||||
/>
|
||||
<CategoriesList
|
||||
iconPad={canAddOtherServers && props.teamsCount <= 1}
|
||||
iconPad={canAddOtherServers && !props.hasMoreThanOneTeam}
|
||||
isCRTEnabled={props.isCRTEnabled}
|
||||
teamsCount={props.teamsCount}
|
||||
channelsCount={props.channelsCount}
|
||||
moreThanOneTeam={props.hasMoreThanOneTeam}
|
||||
hasChannels={props.hasChannels}
|
||||
/>
|
||||
{isTablet &&
|
||||
<AdditionalTabletView/>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import {of as of$} from 'rxjs';
|
||||
import {switchMap} from 'rxjs/operators';
|
||||
import {distinctUntilChanged, switchMap} from 'rxjs/operators';
|
||||
|
||||
import {queryAllMyChannelsForTeam} from '@queries/servers/channel';
|
||||
import {observeCurrentTeamId, observeLicense} from '@queries/servers/system';
|
||||
@@ -21,11 +21,22 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
switchMap((lcs) => (lcs ? of$(lcs.IsLicensed === 'true') : of$(false))),
|
||||
);
|
||||
|
||||
const teamsCount = queryMyTeams(database).observeCount(false);
|
||||
|
||||
return {
|
||||
isCRTEnabled: observeIsCRTEnabled(database),
|
||||
teamsCount: queryMyTeams(database).observeCount(false),
|
||||
channelsCount: observeCurrentTeamId(database).pipe(
|
||||
hasTeams: teamsCount.pipe(
|
||||
switchMap((v) => of$(v > 0)),
|
||||
distinctUntilChanged(),
|
||||
),
|
||||
hasMoreThanOneTeam: teamsCount.pipe(
|
||||
switchMap((v) => of$(v > 1)),
|
||||
distinctUntilChanged(),
|
||||
),
|
||||
hasChannels: observeCurrentTeamId(database).pipe(
|
||||
switchMap((id) => (id ? queryAllMyChannelsForTeam(database, id).observeCount(false) : of$(0))),
|
||||
switchMap((v) => of$(v > 0)),
|
||||
distinctUntilChanged(),
|
||||
),
|
||||
isLicensed,
|
||||
showToS: observeShowToS(database),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import {General, Preferences} from '@constants';
|
||||
import {DMS_CATEGORY} from '@constants/categories';
|
||||
import {getPreferenceAsBool, getPreferenceValue} from '@helpers/api/preference';
|
||||
import {getPreferenceAsBool} from '@helpers/api/preference';
|
||||
import {isDMorGM} from '@utils/channel';
|
||||
import {getUserIdFromChannelName} from '@utils/user';
|
||||
|
||||
@@ -42,15 +42,18 @@ export const filterAutoclosedDMs = (
|
||||
// Only autoclose DMs that haven't been assigned to a category
|
||||
return channelsWithMyChannel;
|
||||
}
|
||||
|
||||
const prefMap = preferences.reduce((acc, v) => {
|
||||
const existing = acc.get(v.name);
|
||||
acc.set(v.name, Math.max((v.value as unknown as number) || 0, existing || 0));
|
||||
return acc;
|
||||
}, new Map<string, number>());
|
||||
const getLastViewedAt = (cwm: ChannelWithMyChannel) => {
|
||||
// The server only ever sets the last_viewed_at to the time of the last post in channel, so we may need
|
||||
// to use the preferences added for the previous version of autoclosing DMs.
|
||||
const id = cwm.channel.id;
|
||||
return Math.max(
|
||||
cwm.myChannel.lastViewedAt,
|
||||
getPreferenceValue<number>(preferences, Preferences.CATEGORIES.CHANNEL_APPROXIMATE_VIEW_TIME, id, 0),
|
||||
getPreferenceValue<number>(preferences, Preferences.CATEGORIES.CHANNEL_OPEN_TIME, id, 0),
|
||||
prefMap.get(id) || 0,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -178,7 +181,7 @@ export const sortChannels = (sorting: CategorySorting, channelsWithMyChannel: Ch
|
||||
}).map((cwm) => cwm.channel);
|
||||
} else if (sorting === 'manual') {
|
||||
return channelsWithMyChannel.sort((cwmA, cwmB) => {
|
||||
return cwmB.sortOrder - cwmA.sortOrder;
|
||||
return cwmA.sortOrder - cwmB.sortOrder;
|
||||
}).map((cwm) => cwm.channel);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
import {isMinimumServerVersion} from './helpers';
|
||||
|
||||
export function hasReliableWebsocket(config: ClientConfig) {
|
||||
if (isMinimumServerVersion(config.Version, 6, 5)) {
|
||||
export function hasReliableWebsocket(version?: string, reliableWebsocketsConfig?: string) {
|
||||
if (version && isMinimumServerVersion(version, 6, 5)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return config.EnableReliableWebSockets === 'true';
|
||||
return reliableWebsocketsConfig === 'true';
|
||||
}
|
||||
|
||||
1
assets/base/i18n/ar.json
Normal file
1
assets/base/i18n/ar.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -321,7 +321,7 @@
|
||||
"post_body.check_for_out_of_channel_groups_mentions.message": "nie zostali powiadomieni poprzez tą wzmiankę, ponieważ nie są na kanale. Nie można ich dodać do kanału, ponieważ nie są członkami grup połączonych. Aby dodać je do tego kanału, muszą zostać dodane do połączonych grup.",
|
||||
"post_body.check_for_out_of_channel_mentions.link.and": " i ",
|
||||
"post_body.check_for_out_of_channel_mentions.link.private": "dodaj je do tego prywatnego kanału",
|
||||
"post_body.check_for_out_of_channel_mentions.link.public": "dodaj je do kanału",
|
||||
"post_body.check_for_out_of_channel_mentions.link.public": "dodać ich do kanału",
|
||||
"post_body.check_for_out_of_channel_mentions.message_last": "? Będą mieć dostęp do całej historii wiadomości.",
|
||||
"post_body.check_for_out_of_channel_mentions.message.multiple": "zostały wspomniane, ale nie są w kanale. Czy chciałbyś ",
|
||||
"post_body.check_for_out_of_channel_mentions.message.one": "został wspomniany, ale nie ma go w kanale. Czy chciałbyś ",
|
||||
|
||||
@@ -433,7 +433,7 @@
|
||||
"mobile.create_direct_message.you": "@{username} - вы",
|
||||
"mobile.create_direct_message.start": "Начать разговор",
|
||||
"mobile.create_channel.title": "Новый канал",
|
||||
"mobile.components.select_server_view.msg_description": "Сервер - это коммуникационный узел вашей команды, доступ к которому осуществляется через уникальный URL-адрес",
|
||||
"mobile.components.select_server_view.msg_description": "Сервер - это коммуникационный узел вашей команды, доступ к которому осуществляется по уникальному URL-адресу",
|
||||
"mobile.components.select_server_view.msg_connect": "Давайте подключимся к серверу",
|
||||
"mobile.components.select_server_view.displayName": "Отображаемое имя",
|
||||
"mobile.components.select_server_view.displayHelp": "Выберите отображаемое имя для вашего сервера",
|
||||
@@ -992,5 +992,19 @@
|
||||
"mobile.calls_recording_start_no_permissions": "У вас нет прав для начала записи. Пожалуйста, попросите ведущего звонка начать запись.",
|
||||
"mobile.calls_recording_start_in_progress": "Запись уже ведется.",
|
||||
"mobile.calls_host_rec_error_title": "Что-то пошло не так с записью",
|
||||
"mobile.calls_host_rec_error": "Пожалуйста, попробуйте записать еще раз. Вы также можете обратиться к системному администратору за помощью в устранении неполадок."
|
||||
"mobile.calls_host_rec_error": "Пожалуйста, попробуйте записать еще раз. Вы также можете обратиться к системному администратору за помощью в устранении неполадок.",
|
||||
"notification.no_post": "Сообщение не найдено.",
|
||||
"notification.no_connection": "Сервер недоступен, и мы не смогли получить уведомления канала / команды.",
|
||||
"invite.summary.back": "Вернуться назад",
|
||||
"channel_notification_preferences.unmute_content": "Включить уведомления",
|
||||
"channel_notification_preferences.thread_replies": "Ответы на обсуждения",
|
||||
"channel_notification_preferences.reset_default": "Сбросить до значений по умолчанию",
|
||||
"channel_notification_preferences.notify_about": "Уведомить меня о...",
|
||||
"channel_notification_preferences.notification.thread_replies": "Уведомлять меня об ответах на обсуждения, за которыми я слежу в этом канале",
|
||||
"channel_notification_preferences.notification.none": "Ничего",
|
||||
"channel_notification_preferences.notification.mention": "Только упоминания, личные сообщения",
|
||||
"channel_notification_preferences.notification.all": "Все новые сообщения",
|
||||
"channel_notification_preferences.muted_title": "На этом канале уведомления отключены",
|
||||
"channel_notification_preferences.muted_content": "Вы можете изменить настройки уведомлений, но вы не будете получать уведомления, пока вы не включите их для канала обратно.",
|
||||
"channel_notification_preferences.default": "(по умолчанию)"
|
||||
}
|
||||
|
||||
@@ -992,5 +992,18 @@
|
||||
"mobile.calls_recording_start_no_permissions": "Du har inte behörighet att starta en inspelning. Be samtalsvärden att starta en inspelning.",
|
||||
"mobile.calls_recording_start_in_progress": "En inspelning pågår redan.",
|
||||
"mobile.calls_host_rec_error_title": "Något gick fel med inspelningen",
|
||||
"mobile.calls_host_rec_error": "Försök att spela in igen. Du kan också kontakta din systemadministratör för att få hjälp med felsökning."
|
||||
"mobile.calls_host_rec_error": "Försök att spela in igen. Du kan också kontakta din systemadministratör för att få hjälp med felsökning.",
|
||||
"notification.no_post": "Meddelandet hittades inte.",
|
||||
"invite.summary.back": "Gå tillbaka",
|
||||
"channel_notification_preferences.unmute_content": "Stäng av mjutad kanal",
|
||||
"channel_notification_preferences.thread_replies": "Svar i trådar",
|
||||
"channel_notification_preferences.reset_default": "Återställ till standardinställningen",
|
||||
"channel_notification_preferences.notify_about": "Notifiera mig om...",
|
||||
"channel_notification_preferences.notification.thread_replies": "Notifiera mig om svar i trådar som jag följer i denna kanal",
|
||||
"channel_notification_preferences.notification.none": "Inget",
|
||||
"channel_notification_preferences.notification.mention": "Endast omnämnanden och direktmeddelanden",
|
||||
"channel_notification_preferences.notification.all": "Alla nya meddelanden",
|
||||
"channel_notification_preferences.muted_title": "Kanalen är mjutad",
|
||||
"channel_notification_preferences.muted_content": "Du kan ändra notifieringsinställningarna, men eftersom kanalen är mjutad kommer du inte få notifieringar.",
|
||||
"channel_notification_preferences.default": "(standard)"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {isIos, timeouts, wait} from '@support/utils';
|
||||
import {isAndroid, isIos, timeouts, wait} from '@support/utils';
|
||||
import {expect} from 'detox';
|
||||
|
||||
class ServerScreen {
|
||||
@@ -47,7 +47,9 @@ class ServerScreen {
|
||||
await this.serverUrlInput.replaceText(serverUrl);
|
||||
await this.serverUrlInput.tapReturnKey();
|
||||
await this.serverDisplayNameInput.replaceText(serverDisplayName);
|
||||
await this.serverDisplayNameInput.tapReturnKey();
|
||||
if (isAndroid()) {
|
||||
await this.serverDisplayNameInput.tapReturnKey();
|
||||
}
|
||||
if (isIos()) {
|
||||
await this.tapConnectButton();
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ describe('Channels - Channel List', () => {
|
||||
// * Verify on first channel
|
||||
await ChannelScreen.toBeVisible();
|
||||
await expect(ChannelScreen.headerTitle).toHaveText(testChannel.display_name);
|
||||
await expect(ChannelScreen.introDisplayName).toHaveText(testChannel.display_name);
|
||||
|
||||
// # Go back to channel list screen and tap on a second channel
|
||||
await ChannelScreen.back();
|
||||
@@ -92,7 +91,15 @@ describe('Channels - Channel List', () => {
|
||||
// * Verify on second channel
|
||||
await ChannelScreen.toBeVisible();
|
||||
await expect(ChannelScreen.headerTitle).toHaveText('Off-Topic');
|
||||
await expect(ChannelScreen.introDisplayName).toHaveText('Off-Topic');
|
||||
|
||||
// # Go back to channel list screen and tap on a third channel
|
||||
await ChannelScreen.back();
|
||||
await ChannelListScreen.toBeVisible();
|
||||
await ChannelListScreen.getChannelItemDisplayName(channelsCategory, townSquareChannelName).tap();
|
||||
|
||||
// * Verify on third channel
|
||||
await ChannelScreen.toBeVisible();
|
||||
await expect(ChannelScreen.headerTitle).toHaveText('Town Square');
|
||||
|
||||
// # Go back to channel list screen
|
||||
await ChannelScreen.back();
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.5)
|
||||
CFPropertyList (3.0.6)
|
||||
rexml
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
artifactory (3.0.15)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.695.0)
|
||||
aws-sdk-core (3.169.0)
|
||||
aws-partitions (1.721.0)
|
||||
aws-sdk-core (3.170.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.62.0)
|
||||
aws-sdk-kms (1.63.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.118.0)
|
||||
aws-sdk-s3 (1.119.1)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
@@ -36,7 +36,7 @@ GEM
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.8.1)
|
||||
emoji_regex (3.2.3)
|
||||
excon (0.97.1)
|
||||
excon (0.99.0)
|
||||
faraday (1.10.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
@@ -66,7 +66,7 @@ GEM
|
||||
faraday_middleware (1.2.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.6)
|
||||
fastlane (2.211.0)
|
||||
fastlane (2.212.1)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.8, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
@@ -109,11 +109,11 @@ GEM
|
||||
fastlane-plugin-android_change_string_app_name (0.1.1)
|
||||
nokogiri
|
||||
fastlane-plugin-find_replace_string (0.1.0)
|
||||
fastlane-plugin-versioning_android (0.1.0)
|
||||
fastlane-plugin-versioning_android (0.1.1)
|
||||
gh_inspector (1.1.3)
|
||||
google-apis-androidpublisher_v3 (0.32.0)
|
||||
google-apis-core (>= 0.9.1, < 2.a)
|
||||
google-apis-core (0.9.5)
|
||||
google-apis-androidpublisher_v3 (0.35.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-core (0.11.0)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
httpclient (>= 2.8.1, < 3.a)
|
||||
@@ -122,10 +122,10 @@ GEM
|
||||
retriable (>= 2.0, < 4.a)
|
||||
rexml
|
||||
webrick
|
||||
google-apis-iamcredentials_v1 (0.16.0)
|
||||
google-apis-core (>= 0.9.1, < 2.a)
|
||||
google-apis-playcustomapp_v1 (0.12.0)
|
||||
google-apis-core (>= 0.9.1, < 2.a)
|
||||
google-apis-iamcredentials_v1 (0.17.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-playcustomapp_v1 (0.13.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-storage_v1 (0.19.0)
|
||||
google-apis-core (>= 0.9.0, < 2.a)
|
||||
google-cloud-core (1.6.0)
|
||||
@@ -133,7 +133,7 @@ GEM
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.6.0)
|
||||
faraday (>= 0.17.3, < 3.0)
|
||||
google-cloud-errors (1.3.0)
|
||||
google-cloud-errors (1.3.1)
|
||||
google-cloud-storage (1.44.0)
|
||||
addressable (~> 2.8)
|
||||
digest-crc (~> 0.4)
|
||||
@@ -155,7 +155,7 @@ GEM
|
||||
httpclient (2.8.3)
|
||||
jmespath (1.6.2)
|
||||
json (2.6.3)
|
||||
jwt (2.6.0)
|
||||
jwt (2.7.0)
|
||||
memoist (0.16.2)
|
||||
mini_magick (4.12.0)
|
||||
mini_mime (1.1.2)
|
||||
@@ -164,12 +164,12 @@ GEM
|
||||
multipart-post (2.0.0)
|
||||
nanaimo (0.3.0)
|
||||
naturally (2.2.1)
|
||||
nokogiri (1.14.0)
|
||||
nokogiri (1.14.2)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
optparse (0.1.1)
|
||||
os (1.1.4)
|
||||
plist (3.6.0)
|
||||
plist (3.7.0)
|
||||
public_suffix (5.0.1)
|
||||
racc (1.6.2)
|
||||
rake (13.0.6)
|
||||
@@ -188,7 +188,7 @@ GEM
|
||||
faraday (>= 0.17.5, < 3.a)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simctl (1.6.8)
|
||||
simctl (1.6.10)
|
||||
CFPropertyList
|
||||
naturally
|
||||
slack-notifier (2.3.2)
|
||||
@@ -205,7 +205,7 @@ GEM
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (1.8.0)
|
||||
webrick (1.7.0)
|
||||
webrick (1.8.1)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.22.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
|
||||
@@ -1128,7 +1128,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 460;
|
||||
CURRENT_PROJECT_VERSION = 461;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
ENABLE_BITCODE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
@@ -1172,7 +1172,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 460;
|
||||
CURRENT_PROJECT_VERSION = 461;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
ENABLE_BITCODE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
@@ -1315,7 +1315,7 @@
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 460;
|
||||
CURRENT_PROJECT_VERSION = 461;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
@@ -1366,7 +1366,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 460;
|
||||
CURRENT_PROJECT_VERSION = 461;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>460</string>
|
||||
<string>461</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>460</string>
|
||||
<string>461</string>
|
||||
<key>UIAppFonts</key>
|
||||
<array>
|
||||
<string>OpenSans-Bold.ttf</string>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>460</string>
|
||||
<string>461</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
|
||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -19,7 +19,7 @@
|
||||
"@gorhom/bottom-sheet": "4.4.5",
|
||||
"@mattermost/compass-icons": "0.1.35",
|
||||
"@mattermost/react-native-emm": "1.3.5",
|
||||
"@mattermost/react-native-network-client": "1.3.1",
|
||||
"@mattermost/react-native-network-client": "1.3.2",
|
||||
"@mattermost/react-native-paste-input": "0.6.2",
|
||||
"@mattermost/react-native-turbo-log": "0.2.3",
|
||||
"@mattermost/react-native-turbo-mailer": "0.2.4",
|
||||
@@ -3241,9 +3241,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mattermost/react-native-network-client": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.3.1.tgz",
|
||||
"integrity": "sha512-DtwVLV/NUE6MkXOlVZG+4QJXou6nHMdmsxnP1+RqhOeSw5jJlQvxmQgxzxvxLpaWOag+wgB1zpDulGNbr/Cz6Q==",
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.3.2.tgz",
|
||||
"integrity": "sha512-3GFNzMXZWlIXXDYQLIJlKRf+HUZKP0F7mpZ1rSTgoTmUeFdqde4uRiU/L96COg34rAdeFRFrgpk0DxEnT7NiVg==",
|
||||
"dependencies": {
|
||||
"validator": "13.9.0",
|
||||
"zod": "3.20.6"
|
||||
@@ -24297,9 +24297,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@mattermost/react-native-network-client": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.3.1.tgz",
|
||||
"integrity": "sha512-DtwVLV/NUE6MkXOlVZG+4QJXou6nHMdmsxnP1+RqhOeSw5jJlQvxmQgxzxvxLpaWOag+wgB1zpDulGNbr/Cz6Q==",
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.3.2.tgz",
|
||||
"integrity": "sha512-3GFNzMXZWlIXXDYQLIJlKRf+HUZKP0F7mpZ1rSTgoTmUeFdqde4uRiU/L96COg34rAdeFRFrgpk0DxEnT7NiVg==",
|
||||
"requires": {
|
||||
"validator": "13.9.0",
|
||||
"zod": "3.20.6"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"@gorhom/bottom-sheet": "4.4.5",
|
||||
"@mattermost/compass-icons": "0.1.35",
|
||||
"@mattermost/react-native-emm": "1.3.5",
|
||||
"@mattermost/react-native-network-client": "1.3.1",
|
||||
"@mattermost/react-native-network-client": "1.3.2",
|
||||
"@mattermost/react-native-paste-input": "0.6.2",
|
||||
"@mattermost/react-native-turbo-log": "0.2.3",
|
||||
"@mattermost/react-native-turbo-mailer": "0.2.4",
|
||||
|
||||
Reference in New Issue
Block a user