Merge branch 'develop' into chore.console-error
This commit is contained in:
commit
6168926600
|
@ -359,7 +359,7 @@ jobs:
|
||||||
- run:
|
- run:
|
||||||
name: Test
|
name: Test
|
||||||
command: |
|
command: |
|
||||||
yarn test
|
yarn test -w 8
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Codecov
|
name: Codecov
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import initStoryshots from '@storybook/addon-storyshots';
|
import initStoryshots, { Stories2SnapsConverter } from '@storybook/addon-storyshots';
|
||||||
|
import { render } from '@testing-library/react-native';
|
||||||
|
|
||||||
jest.mock('rn-fetch-blob', () => ({
|
jest.mock('rn-fetch-blob', () => ({
|
||||||
fs: {
|
fs: {
|
||||||
|
@ -19,4 +20,15 @@ jest.mock('react-native-file-viewer', () => ({
|
||||||
jest.mock('../app/lib/database', () => jest.fn(() => null));
|
jest.mock('../app/lib/database', () => jest.fn(() => null));
|
||||||
global.Date.now = jest.fn(() => new Date('2019-10-10').getTime());
|
global.Date.now = jest.fn(() => new Date('2019-10-10').getTime());
|
||||||
|
|
||||||
initStoryshots();
|
const converter = new Stories2SnapsConverter();
|
||||||
|
|
||||||
|
initStoryshots({
|
||||||
|
test: ({ story, context }) => {
|
||||||
|
const snapshotFilename = converter.getSnapshotFileName(context);
|
||||||
|
const storyElement = story.render();
|
||||||
|
const { update, toJSON } = render(storyElement);
|
||||||
|
update(storyElement);
|
||||||
|
const json = toJSON();
|
||||||
|
expect(JSON.stringify(json)).toMatchSpecificSnapshot(snapshotFilename);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,7 @@ import { connect } from 'react-redux';
|
||||||
import { SetUsernameStackParamList, StackParamList } from './definitions/navigationTypes';
|
import { SetUsernameStackParamList, StackParamList } from './definitions/navigationTypes';
|
||||||
import Navigation from './lib/Navigation';
|
import Navigation from './lib/Navigation';
|
||||||
import { defaultHeader, getActiveRouteName, navigationTheme } from './utils/navigation';
|
import { defaultHeader, getActiveRouteName, navigationTheme } from './utils/navigation';
|
||||||
import { ROOT_INSIDE, ROOT_LOADING, ROOT_OUTSIDE, ROOT_SET_USERNAME } from './actions/app';
|
import { RootEnum } from './definitions';
|
||||||
// Stacks
|
// Stacks
|
||||||
import AuthLoadingView from './views/AuthLoadingView';
|
import AuthLoadingView from './views/AuthLoadingView';
|
||||||
// SetUsername Stack
|
// SetUsername Stack
|
||||||
|
@ -56,13 +56,13 @@ const App = React.memo(({ root, isMasterDetail }: { root: string; isMasterDetail
|
||||||
}}>
|
}}>
|
||||||
<Stack.Navigator screenOptions={{ headerShown: false, animationEnabled: false }}>
|
<Stack.Navigator screenOptions={{ headerShown: false, animationEnabled: false }}>
|
||||||
<>
|
<>
|
||||||
{root === ROOT_LOADING ? <Stack.Screen name='AuthLoading' component={AuthLoadingView} /> : null}
|
{root === RootEnum.ROOT_LOADING ? <Stack.Screen name='AuthLoading' component={AuthLoadingView} /> : null}
|
||||||
{root === ROOT_OUTSIDE ? <Stack.Screen name='OutsideStack' component={OutsideStack} /> : null}
|
{root === RootEnum.ROOT_OUTSIDE ? <Stack.Screen name='OutsideStack' component={OutsideStack} /> : null}
|
||||||
{root === ROOT_INSIDE && isMasterDetail ? (
|
{root === RootEnum.ROOT_INSIDE && isMasterDetail ? (
|
||||||
<Stack.Screen name='MasterDetailStack' component={MasterDetailStack} />
|
<Stack.Screen name='MasterDetailStack' component={MasterDetailStack} />
|
||||||
) : null}
|
) : null}
|
||||||
{root === ROOT_INSIDE && !isMasterDetail ? <Stack.Screen name='InsideStack' component={InsideStack} /> : null}
|
{root === RootEnum.ROOT_INSIDE && !isMasterDetail ? <Stack.Screen name='InsideStack' component={InsideStack} /> : null}
|
||||||
{root === ROOT_SET_USERNAME ? <Stack.Screen name='SetUsernameStack' component={SetUsernameStack} /> : null}
|
{root === RootEnum.ROOT_SET_USERNAME ? <Stack.Screen name='SetUsernameStack' component={SetUsernameStack} /> : null}
|
||||||
</>
|
</>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
</NavigationContainer>
|
</NavigationContainer>
|
||||||
|
|
|
@ -2,8 +2,8 @@ const REQUEST = 'REQUEST';
|
||||||
const SUCCESS = 'SUCCESS';
|
const SUCCESS = 'SUCCESS';
|
||||||
const FAILURE = 'FAILURE';
|
const FAILURE = 'FAILURE';
|
||||||
const defaultTypes = [REQUEST, SUCCESS, FAILURE];
|
const defaultTypes = [REQUEST, SUCCESS, FAILURE];
|
||||||
function createRequestTypes(base = {}, types = defaultTypes): Record<any, any> {
|
function createRequestTypes(base = {}, types = defaultTypes): Record<string, string> {
|
||||||
const res: Record<any, any> = {};
|
const res: Record<string, string> = {};
|
||||||
types.forEach(type => (res[type] = `${base}_${type}`));
|
types.forEach(type => (res[type] = `${base}_${type}`));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Action } from 'redux';
|
||||||
import { IActiveUsers } from '../reducers/activeUsers';
|
import { IActiveUsers } from '../reducers/activeUsers';
|
||||||
import { SET_ACTIVE_USERS } from './actionsTypes';
|
import { SET_ACTIVE_USERS } from './actionsTypes';
|
||||||
|
|
||||||
export interface ISetActiveUsers extends Action {
|
interface ISetActiveUsers extends Action {
|
||||||
activeUsers: IActiveUsers;
|
activeUsers: IActiveUsers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
import { APP } from './actionsTypes';
|
|
||||||
|
|
||||||
export const ROOT_OUTSIDE = 'outside';
|
|
||||||
export const ROOT_INSIDE = 'inside';
|
|
||||||
export const ROOT_LOADING = 'loading';
|
|
||||||
export const ROOT_SET_USERNAME = 'setUsername';
|
|
||||||
|
|
||||||
export function appStart({ root, ...args }) {
|
|
||||||
return {
|
|
||||||
type: APP.START,
|
|
||||||
root,
|
|
||||||
...args
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function appReady() {
|
|
||||||
return {
|
|
||||||
type: APP.READY
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function appInit() {
|
|
||||||
return {
|
|
||||||
type: APP.INIT
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function appInitLocalSettings() {
|
|
||||||
return {
|
|
||||||
type: APP.INIT_LOCAL_SETTINGS
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setMasterDetail(isMasterDetail) {
|
|
||||||
return {
|
|
||||||
type: APP.SET_MASTER_DETAIL,
|
|
||||||
isMasterDetail
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { RootEnum } from '../definitions';
|
||||||
|
import { APP } from './actionsTypes';
|
||||||
|
|
||||||
|
interface IAppStart extends Action {
|
||||||
|
root: RootEnum;
|
||||||
|
text?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISetMasterDetail extends Action {
|
||||||
|
isMasterDetail: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionApp = IAppStart & ISetMasterDetail;
|
||||||
|
|
||||||
|
interface Params {
|
||||||
|
root: RootEnum;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function appStart({ root, ...args }: Params): IAppStart {
|
||||||
|
return {
|
||||||
|
type: APP.START,
|
||||||
|
root,
|
||||||
|
...args
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function appReady(): Action {
|
||||||
|
return {
|
||||||
|
type: APP.READY
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function appInit(): Action {
|
||||||
|
return {
|
||||||
|
type: APP.INIT
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function appInitLocalSettings(): Action {
|
||||||
|
return {
|
||||||
|
type: APP.INIT_LOCAL_SETTINGS
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setMasterDetail(isMasterDetail: boolean): ISetMasterDetail {
|
||||||
|
return {
|
||||||
|
type: APP.SET_MASTER_DETAIL,
|
||||||
|
isMasterDetail
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function connectRequest() {
|
|
||||||
return {
|
|
||||||
type: types.METEOR.REQUEST
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function connectSuccess() {
|
|
||||||
return {
|
|
||||||
type: types.METEOR.SUCCESS
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function disconnect(err) {
|
|
||||||
return {
|
|
||||||
type: types.METEOR.DISCONNECT,
|
|
||||||
err
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import * as types from './actionsTypes';
|
||||||
|
|
||||||
|
export function connectRequest(): Action {
|
||||||
|
return {
|
||||||
|
type: types.METEOR.REQUEST
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function connectSuccess(): Action {
|
||||||
|
return {
|
||||||
|
type: types.METEOR.SUCCESS
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function disconnect(): Action {
|
||||||
|
return {
|
||||||
|
type: types.METEOR.DISCONNECT
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,23 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function createChannelRequest(data) {
|
|
||||||
return {
|
|
||||||
type: types.CREATE_CHANNEL.REQUEST,
|
|
||||||
data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createChannelSuccess(data) {
|
|
||||||
return {
|
|
||||||
type: types.CREATE_CHANNEL.SUCCESS,
|
|
||||||
data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createChannelFailure(err, isTeam) {
|
|
||||||
return {
|
|
||||||
type: types.CREATE_CHANNEL.FAILURE,
|
|
||||||
err,
|
|
||||||
isTeam
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { TCreateChannelResult } from '../reducers/createChannel';
|
||||||
|
import { CREATE_CHANNEL } from './actionsTypes';
|
||||||
|
|
||||||
|
interface ICreateChannelRequest extends Action {
|
||||||
|
data: TCreateChannelResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICreateChannelSuccess extends Action {
|
||||||
|
data: TCreateChannelResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICreateChannelFailure extends Action {
|
||||||
|
err: any;
|
||||||
|
isTeam: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionCreateChannel = ICreateChannelRequest & ICreateChannelSuccess & ICreateChannelFailure;
|
||||||
|
|
||||||
|
export function createChannelRequest(data: TCreateChannelResult): ICreateChannelRequest {
|
||||||
|
return {
|
||||||
|
type: CREATE_CHANNEL.REQUEST,
|
||||||
|
data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createChannelSuccess(data: TCreateChannelResult): ICreateChannelSuccess {
|
||||||
|
return {
|
||||||
|
type: CREATE_CHANNEL.SUCCESS,
|
||||||
|
data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createChannelFailure(err: any, isTeam: boolean): ICreateChannelFailure {
|
||||||
|
return {
|
||||||
|
type: CREATE_CHANNEL.FAILURE,
|
||||||
|
err,
|
||||||
|
isTeam
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,22 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function createDiscussionRequest(data) {
|
|
||||||
return {
|
|
||||||
type: types.CREATE_DISCUSSION.REQUEST,
|
|
||||||
data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createDiscussionSuccess(data) {
|
|
||||||
return {
|
|
||||||
type: types.CREATE_DISCUSSION.SUCCESS,
|
|
||||||
data
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createDiscussionFailure(err) {
|
|
||||||
return {
|
|
||||||
type: types.CREATE_DISCUSSION.FAILURE,
|
|
||||||
err
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { CREATE_DISCUSSION } from './actionsTypes';
|
||||||
|
|
||||||
|
interface ICreateDiscussionRequest extends Action {
|
||||||
|
data: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICreateDiscussionSuccess extends Action {
|
||||||
|
data: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ICreateDiscussionFailure extends Action {
|
||||||
|
err: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionCreateDiscussion = ICreateDiscussionRequest & ICreateDiscussionSuccess & ICreateDiscussionFailure;
|
||||||
|
|
||||||
|
export function createDiscussionRequest(data: any): ICreateDiscussionRequest {
|
||||||
|
return {
|
||||||
|
type: CREATE_DISCUSSION.REQUEST,
|
||||||
|
data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createDiscussionSuccess(data: any): ICreateDiscussionSuccess {
|
||||||
|
return {
|
||||||
|
type: CREATE_DISCUSSION.SUCCESS,
|
||||||
|
data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createDiscussionFailure(err: any): ICreateDiscussionFailure {
|
||||||
|
return {
|
||||||
|
type: CREATE_DISCUSSION.FAILURE,
|
||||||
|
err
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function setCustomEmojis(emojis) {
|
|
||||||
return {
|
|
||||||
type: types.SET_CUSTOM_EMOJIS,
|
|
||||||
emojis
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { ICustomEmojis } from '../reducers/customEmojis';
|
||||||
|
import { SET_CUSTOM_EMOJIS } from './actionsTypes';
|
||||||
|
|
||||||
|
export interface ISetCustomEmojis extends Action {
|
||||||
|
emojis: ICustomEmojis;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionCustomEmojis = ISetCustomEmojis;
|
||||||
|
|
||||||
|
export function setCustomEmojis(emojis: ICustomEmojis): ISetCustomEmojis {
|
||||||
|
return {
|
||||||
|
type: SET_CUSTOM_EMOJIS,
|
||||||
|
emojis
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function deepLinkingOpen(params) {
|
|
||||||
return {
|
|
||||||
type: types.DEEP_LINKING.OPEN,
|
|
||||||
params
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { DEEP_LINKING } from './actionsTypes';
|
||||||
|
|
||||||
|
interface IParams {
|
||||||
|
path: string;
|
||||||
|
rid: string;
|
||||||
|
messageId: string;
|
||||||
|
host: string;
|
||||||
|
isCall: boolean;
|
||||||
|
fullURL: string;
|
||||||
|
type: string;
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDeepLinkingOpen extends Action {
|
||||||
|
params: Partial<IParams>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deepLinkingOpen(params: Partial<IParams>): IDeepLinkingOpen {
|
||||||
|
return {
|
||||||
|
type: DEEP_LINKING.OPEN,
|
||||||
|
params
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function encryptionInit() {
|
|
||||||
return {
|
|
||||||
type: types.ENCRYPTION.INIT
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function encryptionStop() {
|
|
||||||
return {
|
|
||||||
type: types.ENCRYPTION.STOP
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function encryptionSet(enabled = false, banner = null) {
|
|
||||||
return {
|
|
||||||
type: types.ENCRYPTION.SET,
|
|
||||||
enabled,
|
|
||||||
banner
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function encryptionSetBanner(banner) {
|
|
||||||
return {
|
|
||||||
type: types.ENCRYPTION.SET_BANNER,
|
|
||||||
banner
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function encryptionDecodeKey(password) {
|
|
||||||
return {
|
|
||||||
type: types.ENCRYPTION.DECODE_KEY,
|
|
||||||
password
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { IBanner } from '../reducers/encryption';
|
||||||
|
import { ENCRYPTION } from './actionsTypes';
|
||||||
|
|
||||||
|
export interface IEncryptionSet extends Action {
|
||||||
|
enabled: boolean;
|
||||||
|
banner: IBanner;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IEncryptionSetBanner extends Action {
|
||||||
|
banner: IBanner;
|
||||||
|
}
|
||||||
|
export interface IEncryptionDecodeKey extends Action {
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionEncryption = IEncryptionSet & IEncryptionSetBanner & IEncryptionDecodeKey;
|
||||||
|
|
||||||
|
export function encryptionInit(): Action {
|
||||||
|
return {
|
||||||
|
type: ENCRYPTION.INIT
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encryptionStop(): Action {
|
||||||
|
return {
|
||||||
|
type: ENCRYPTION.STOP
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encryptionSet(enabled = false, banner: IBanner = ''): IEncryptionSet {
|
||||||
|
return {
|
||||||
|
type: ENCRYPTION.SET,
|
||||||
|
enabled,
|
||||||
|
banner
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encryptionSetBanner(banner: IBanner = ''): IEncryptionSetBanner {
|
||||||
|
return {
|
||||||
|
type: ENCRYPTION.SET_BANNER,
|
||||||
|
banner
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encryptionDecodeKey(password: string): IEncryptionDecodeKey {
|
||||||
|
return {
|
||||||
|
type: ENCRYPTION.DECODE_KEY,
|
||||||
|
password
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function inviteLinksSetToken(token) {
|
|
||||||
return {
|
|
||||||
type: types.INVITE_LINKS.SET_TOKEN,
|
|
||||||
token
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inviteLinksRequest(token) {
|
|
||||||
return {
|
|
||||||
type: types.INVITE_LINKS.REQUEST,
|
|
||||||
token
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inviteLinksSuccess() {
|
|
||||||
return {
|
|
||||||
type: types.INVITE_LINKS.SUCCESS
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inviteLinksFailure() {
|
|
||||||
return {
|
|
||||||
type: types.INVITE_LINKS.FAILURE
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inviteLinksClear() {
|
|
||||||
return {
|
|
||||||
type: types.INVITE_LINKS.CLEAR
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inviteLinksCreate(rid) {
|
|
||||||
return {
|
|
||||||
type: types.INVITE_LINKS.CREATE,
|
|
||||||
rid
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inviteLinksSetParams(params) {
|
|
||||||
return {
|
|
||||||
type: types.INVITE_LINKS.SET_PARAMS,
|
|
||||||
params
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inviteLinksSetInvite(invite) {
|
|
||||||
return {
|
|
||||||
type: types.INVITE_LINKS.SET_INVITE,
|
|
||||||
invite
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { TInvite } from '../reducers/inviteLinks';
|
||||||
|
import { INVITE_LINKS } from './actionsTypes';
|
||||||
|
|
||||||
|
interface IInviteLinksGeneric extends Action {
|
||||||
|
token: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IInviteLinksCreate extends Action {
|
||||||
|
rid: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IInviteLinksSetInvite extends Action {
|
||||||
|
invite: TInvite;
|
||||||
|
}
|
||||||
|
|
||||||
|
type TParams = Record<string, any>;
|
||||||
|
|
||||||
|
interface IInviteLinksSetParams extends Action {
|
||||||
|
params: TParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionInviteLinks = IInviteLinksGeneric & IInviteLinksCreate & IInviteLinksSetInvite & IInviteLinksSetParams;
|
||||||
|
|
||||||
|
export const inviteLinksSetToken = (token: string): IInviteLinksGeneric => ({
|
||||||
|
type: INVITE_LINKS.SET_TOKEN,
|
||||||
|
token
|
||||||
|
});
|
||||||
|
|
||||||
|
export const inviteLinksRequest = (token: string): IInviteLinksGeneric => ({
|
||||||
|
type: INVITE_LINKS.REQUEST,
|
||||||
|
token
|
||||||
|
});
|
||||||
|
|
||||||
|
export const inviteLinksSuccess = (): Action => ({
|
||||||
|
type: INVITE_LINKS.SUCCESS
|
||||||
|
});
|
||||||
|
|
||||||
|
export const inviteLinksFailure = (): Action => ({
|
||||||
|
type: INVITE_LINKS.FAILURE
|
||||||
|
});
|
||||||
|
|
||||||
|
export const inviteLinksClear = (): Action => ({
|
||||||
|
type: INVITE_LINKS.CLEAR
|
||||||
|
});
|
||||||
|
|
||||||
|
export const inviteLinksCreate = (rid: string): IInviteLinksCreate => ({
|
||||||
|
type: INVITE_LINKS.CREATE,
|
||||||
|
rid
|
||||||
|
});
|
||||||
|
|
||||||
|
export const inviteLinksSetParams = (params: TParams): IInviteLinksSetParams => ({
|
||||||
|
type: INVITE_LINKS.SET_PARAMS,
|
||||||
|
params
|
||||||
|
});
|
||||||
|
|
||||||
|
export const inviteLinksSetInvite = (invite: TInvite): IInviteLinksSetInvite => ({
|
||||||
|
type: INVITE_LINKS.SET_INVITE,
|
||||||
|
invite
|
||||||
|
});
|
|
@ -1,8 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function replyBroadcast(message) {
|
|
||||||
return {
|
|
||||||
type: types.MESSAGES.REPLY_BROADCAST,
|
|
||||||
message
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { MESSAGES } from './actionsTypes';
|
||||||
|
|
||||||
|
type IMessage = Record<string, string>;
|
||||||
|
|
||||||
|
interface IReplyBroadcast extends Action {
|
||||||
|
message: IMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function replyBroadcast(message: IMessage): IReplyBroadcast {
|
||||||
|
return {
|
||||||
|
type: MESSAGES.REPLY_BROADCAST,
|
||||||
|
message
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function setPermissions(permissions) {
|
|
||||||
return {
|
|
||||||
type: types.PERMISSIONS.SET,
|
|
||||||
permissions
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updatePermission(id, roles) {
|
|
||||||
return {
|
|
||||||
type: types.PERMISSIONS.UPDATE,
|
|
||||||
payload: { id, roles }
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { IPermissions } from '../reducers/permissions';
|
||||||
|
import { PERMISSIONS } from './actionsTypes';
|
||||||
|
|
||||||
|
interface ISetPermissions extends Action {
|
||||||
|
permissions: IPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IUpdatePermissions extends Action {
|
||||||
|
payload: { id: string; roles: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionPermissions = ISetPermissions & IUpdatePermissions;
|
||||||
|
|
||||||
|
export function setPermissions(permissions: IPermissions): ISetPermissions {
|
||||||
|
return {
|
||||||
|
type: PERMISSIONS.SET,
|
||||||
|
permissions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updatePermission(id: string, roles: string): IUpdatePermissions {
|
||||||
|
return {
|
||||||
|
type: PERMISSIONS.UPDATE,
|
||||||
|
payload: { id, roles }
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function setRoles(roles) {
|
|
||||||
return {
|
|
||||||
type: types.ROLES.SET,
|
|
||||||
roles
|
|
||||||
};
|
|
||||||
}
|
|
||||||
export function updateRoles(id, desc) {
|
|
||||||
return {
|
|
||||||
type: types.ROLES.UPDATE,
|
|
||||||
payload: { id, desc }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
export function removeRoles(id) {
|
|
||||||
return {
|
|
||||||
type: types.ROLES.REMOVE,
|
|
||||||
payload: { id }
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { IRoles } from '../reducers/roles';
|
||||||
|
import { ROLES } from './actionsTypes';
|
||||||
|
|
||||||
|
export interface ISetRoles extends Action {
|
||||||
|
roles: IRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IUpdateRoles extends Action {
|
||||||
|
payload: { id: string; desc: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IRemoveRoles extends Action {
|
||||||
|
payload: { id: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IActionRoles = ISetRoles & IUpdateRoles & IRemoveRoles;
|
||||||
|
|
||||||
|
export function setRoles(roles: IRoles): ISetRoles {
|
||||||
|
return {
|
||||||
|
type: ROLES.SET,
|
||||||
|
roles
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateRoles(id: string, desc: string): IUpdateRoles {
|
||||||
|
return {
|
||||||
|
type: ROLES.UPDATE,
|
||||||
|
payload: { id, desc }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeRoles(id: string): IRemoveRoles {
|
||||||
|
return {
|
||||||
|
type: ROLES.REMOVE,
|
||||||
|
payload: { id }
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,58 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function roomsRequest(params = { allData: false }) {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.REQUEST,
|
|
||||||
params
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function roomsSuccess() {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.SUCCESS
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function roomsFailure(err) {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.FAILURE,
|
|
||||||
err
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function roomsRefresh() {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.REFRESH
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setSearch(searchText) {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.SET_SEARCH,
|
|
||||||
searchText
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function closeServerDropdown() {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.CLOSE_SERVER_DROPDOWN
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toggleServerDropdown() {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.TOGGLE_SERVER_DROPDOWN
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function openSearchHeader() {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.OPEN_SEARCH_HEADER
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function closeSearchHeader() {
|
|
||||||
return {
|
|
||||||
type: types.ROOMS.CLOSE_SEARCH_HEADER
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { ROOMS } from './actionsTypes';
|
||||||
|
|
||||||
|
export interface IRoomsRequest extends Action {
|
||||||
|
params: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISetSearch extends Action {
|
||||||
|
searchText: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IRoomsFailure extends Action {
|
||||||
|
err: Record<string, any> | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IRoomsAction = IRoomsRequest & ISetSearch & IRoomsFailure;
|
||||||
|
|
||||||
|
export function roomsRequest(
|
||||||
|
params: {
|
||||||
|
allData: boolean;
|
||||||
|
} = { allData: false }
|
||||||
|
): IRoomsRequest {
|
||||||
|
return {
|
||||||
|
type: ROOMS.REQUEST,
|
||||||
|
params
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function roomsSuccess(): Action {
|
||||||
|
return {
|
||||||
|
type: ROOMS.SUCCESS
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function roomsFailure(err: string): IRoomsFailure {
|
||||||
|
return {
|
||||||
|
type: ROOMS.FAILURE,
|
||||||
|
err
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function roomsRefresh(): Action {
|
||||||
|
return {
|
||||||
|
type: ROOMS.REFRESH
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setSearch(searchText: string): ISetSearch {
|
||||||
|
return {
|
||||||
|
type: ROOMS.SET_SEARCH,
|
||||||
|
searchText
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeServerDropdown(): Action {
|
||||||
|
return {
|
||||||
|
type: ROOMS.CLOSE_SERVER_DROPDOWN
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toggleServerDropdown(): Action {
|
||||||
|
return {
|
||||||
|
type: ROOMS.TOGGLE_SERVER_DROPDOWN
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function openSearchHeader(): Action {
|
||||||
|
return {
|
||||||
|
type: ROOMS.OPEN_SEARCH_HEADER
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeSearchHeader(): Action {
|
||||||
|
return {
|
||||||
|
type: ROOMS.CLOSE_SEARCH_HEADER
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,60 +0,0 @@
|
||||||
import { SERVER } from './actionsTypes';
|
|
||||||
|
|
||||||
export function selectServerRequest(server, version, fetchVersion = true, changeServer = false) {
|
|
||||||
return {
|
|
||||||
type: SERVER.SELECT_REQUEST,
|
|
||||||
server,
|
|
||||||
version,
|
|
||||||
fetchVersion,
|
|
||||||
changeServer
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function selectServerSuccess(server, version) {
|
|
||||||
return {
|
|
||||||
type: SERVER.SELECT_SUCCESS,
|
|
||||||
server,
|
|
||||||
version
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function selectServerFailure() {
|
|
||||||
return {
|
|
||||||
type: SERVER.SELECT_FAILURE
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function serverRequest(server, username = null, fromServerHistory = false) {
|
|
||||||
return {
|
|
||||||
type: SERVER.REQUEST,
|
|
||||||
server,
|
|
||||||
username,
|
|
||||||
fromServerHistory
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function serverSuccess() {
|
|
||||||
return {
|
|
||||||
type: SERVER.SUCCESS
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function serverFailure(err) {
|
|
||||||
return {
|
|
||||||
type: SERVER.FAILURE,
|
|
||||||
err
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function serverInitAdd(previousServer) {
|
|
||||||
return {
|
|
||||||
type: SERVER.INIT_ADD,
|
|
||||||
previousServer
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function serverFinishAdd() {
|
|
||||||
return {
|
|
||||||
type: SERVER.FINISH_ADD
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { SERVER } from './actionsTypes';
|
||||||
|
|
||||||
|
interface ISelectServer extends Action {
|
||||||
|
server: string;
|
||||||
|
version?: string;
|
||||||
|
fetchVersion: boolean;
|
||||||
|
changeServer: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISelectServerSuccess extends Action {
|
||||||
|
server: string;
|
||||||
|
version: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IServer extends Action {
|
||||||
|
server: string;
|
||||||
|
username: string | null;
|
||||||
|
fromServerHistory: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IServerInit extends Action {
|
||||||
|
previousServer: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IServerFailure extends Action {
|
||||||
|
err: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionServer = ISelectServer & ISelectServerSuccess & IServer & IServerInit & IServerFailure;
|
||||||
|
|
||||||
|
export function selectServerRequest(server: string, version?: string, fetchVersion = true, changeServer = false): ISelectServer {
|
||||||
|
return {
|
||||||
|
type: SERVER.SELECT_REQUEST,
|
||||||
|
server,
|
||||||
|
version,
|
||||||
|
fetchVersion,
|
||||||
|
changeServer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectServerSuccess(server: string, version: string): ISelectServerSuccess {
|
||||||
|
return {
|
||||||
|
type: SERVER.SELECT_SUCCESS,
|
||||||
|
server,
|
||||||
|
version
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function selectServerFailure(): Action {
|
||||||
|
return {
|
||||||
|
type: SERVER.SELECT_FAILURE
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serverRequest(server: string, username: string | null = null, fromServerHistory = false): IServer {
|
||||||
|
return {
|
||||||
|
type: SERVER.REQUEST,
|
||||||
|
server,
|
||||||
|
username,
|
||||||
|
fromServerHistory
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serverSuccess(): Action {
|
||||||
|
return {
|
||||||
|
type: SERVER.SUCCESS
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serverFailure(err: any): IServerFailure {
|
||||||
|
return {
|
||||||
|
type: SERVER.FAILURE,
|
||||||
|
err
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serverInitAdd(previousServer: string): IServerInit {
|
||||||
|
return {
|
||||||
|
type: SERVER.INIT_ADD,
|
||||||
|
previousServer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serverFinishAdd(): Action {
|
||||||
|
return {
|
||||||
|
type: SERVER.FINISH_ADD
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
import { SETTINGS } from './actionsTypes';
|
|
||||||
|
|
||||||
export function addSettings(settings) {
|
|
||||||
return {
|
|
||||||
type: SETTINGS.ADD,
|
|
||||||
payload: settings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateSettings(id, value) {
|
|
||||||
return {
|
|
||||||
type: SETTINGS.UPDATE,
|
|
||||||
payload: { id, value }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearSettings() {
|
|
||||||
return {
|
|
||||||
type: SETTINGS.CLEAR
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { ISettings, TSettings } from '../reducers/settings';
|
||||||
|
import { SETTINGS } from './actionsTypes';
|
||||||
|
|
||||||
|
interface IAddSettings extends Action {
|
||||||
|
payload: ISettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IUpdateSettings extends Action {
|
||||||
|
payload: { id: string; value: TSettings };
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IActionSettings = IAddSettings & IUpdateSettings;
|
||||||
|
|
||||||
|
export function addSettings(settings: ISettings): IAddSettings {
|
||||||
|
return {
|
||||||
|
type: SETTINGS.ADD,
|
||||||
|
payload: settings
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateSettings(id: string, value: TSettings): IUpdateSettings {
|
||||||
|
return {
|
||||||
|
type: SETTINGS.UPDATE,
|
||||||
|
payload: { id, value }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearSettings(): Action {
|
||||||
|
return {
|
||||||
|
type: SETTINGS.CLEAR
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,22 +0,0 @@
|
||||||
import { SHARE } from './actionsTypes';
|
|
||||||
|
|
||||||
export function shareSelectServer(server) {
|
|
||||||
return {
|
|
||||||
type: SHARE.SELECT_SERVER,
|
|
||||||
server
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function shareSetSettings(settings) {
|
|
||||||
return {
|
|
||||||
type: SHARE.SET_SETTINGS,
|
|
||||||
settings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function shareSetUser(user) {
|
|
||||||
return {
|
|
||||||
type: SHARE.SET_USER,
|
|
||||||
user
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { IShareServer, IShareUser, TShareSettings } from '../reducers/share';
|
||||||
|
import { SHARE } from './actionsTypes';
|
||||||
|
|
||||||
|
interface IShareSelectServer extends Action {
|
||||||
|
server: IShareServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IShareSetSettings extends Action {
|
||||||
|
settings: TShareSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IShareSetUser extends Action {
|
||||||
|
user: IShareUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionsShare = IShareSelectServer & IShareSetSettings & IShareSetUser;
|
||||||
|
|
||||||
|
export function shareSelectServer(server: IShareServer): IShareSelectServer {
|
||||||
|
return {
|
||||||
|
type: SHARE.SELECT_SERVER,
|
||||||
|
server
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function shareSetSettings(settings: TShareSettings): IShareSetSettings {
|
||||||
|
return {
|
||||||
|
type: SHARE.SET_SETTINGS,
|
||||||
|
settings
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function shareSetUser(user: IShareUser): IShareSetUser {
|
||||||
|
return {
|
||||||
|
type: SHARE.SET_USER,
|
||||||
|
user
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
import * as types from './actionsTypes';
|
|
||||||
|
|
||||||
export function setAllPreferences(preferences) {
|
|
||||||
return {
|
|
||||||
type: types.SORT_PREFERENCES.SET_ALL,
|
|
||||||
preferences
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setPreference(preference) {
|
|
||||||
return {
|
|
||||||
type: types.SORT_PREFERENCES.SET,
|
|
||||||
preference
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { IPreferences } from '../definitions';
|
||||||
|
import { SORT_PREFERENCES } from './actionsTypes';
|
||||||
|
|
||||||
|
interface ISetAllPreferences extends Action {
|
||||||
|
preferences: IPreferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISetPreference extends Action {
|
||||||
|
preference: Partial<IPreferences>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionSortPreferences = ISetAllPreferences & ISetPreference;
|
||||||
|
|
||||||
|
export function setAllPreferences(preferences: IPreferences): ISetAllPreferences {
|
||||||
|
return {
|
||||||
|
type: SORT_PREFERENCES.SET_ALL,
|
||||||
|
preferences
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setPreference(preference: Partial<IPreferences>): ISetPreference {
|
||||||
|
return {
|
||||||
|
type: SORT_PREFERENCES.SET,
|
||||||
|
preference
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
import { USERS_TYPING } from './actionsTypes';
|
|
||||||
|
|
||||||
export function addUserTyping(username) {
|
|
||||||
return {
|
|
||||||
type: USERS_TYPING.ADD,
|
|
||||||
username
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function removeUserTyping(username) {
|
|
||||||
return {
|
|
||||||
type: USERS_TYPING.REMOVE,
|
|
||||||
username
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function clearUserTyping() {
|
|
||||||
return {
|
|
||||||
type: USERS_TYPING.CLEAR
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
|
import { USERS_TYPING } from './actionsTypes';
|
||||||
|
|
||||||
|
export interface IUsersTypingGenericAction extends Action {
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionUserTyping = IUsersTypingGenericAction & Action;
|
||||||
|
|
||||||
|
export function addUserTyping(username: string): IUsersTypingGenericAction {
|
||||||
|
return {
|
||||||
|
type: USERS_TYPING.ADD,
|
||||||
|
username
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeUserTyping(username: string): IUsersTypingGenericAction {
|
||||||
|
return {
|
||||||
|
type: USERS_TYPING.REMOVE,
|
||||||
|
username
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearUserTyping(): Action {
|
||||||
|
return {
|
||||||
|
type: USERS_TYPING.CLEAR
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,16 +1,18 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
|
||||||
import database from '../../lib/database';
|
import database from '../../lib/database';
|
||||||
import { getUserSelector } from '../../selectors/login';
|
import { getUserSelector } from '../../selectors/login';
|
||||||
|
import { TSubscriptionModel, TUserModel } from '../../definitions';
|
||||||
import Avatar from './Avatar';
|
import Avatar from './Avatar';
|
||||||
import { IAvatar } from './interfaces';
|
import { IAvatar } from './interfaces';
|
||||||
|
|
||||||
class AvatarContainer extends React.Component<IAvatar, any> {
|
class AvatarContainer extends React.Component<IAvatar, any> {
|
||||||
private mounted: boolean;
|
private mounted: boolean;
|
||||||
|
|
||||||
private subscription: any;
|
private subscription?: Subscription;
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
text: '',
|
text: '',
|
||||||
|
@ -59,15 +61,17 @@ class AvatarContainer extends React.Component<IAvatar, any> {
|
||||||
record = user;
|
record = user;
|
||||||
} else {
|
} else {
|
||||||
const { rid } = this.props;
|
const { rid } = this.props;
|
||||||
|
if (rid) {
|
||||||
record = await subsCollection.find(rid);
|
record = await subsCollection.find(rid);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
// Record not found
|
// Record not found
|
||||||
}
|
}
|
||||||
|
|
||||||
if (record) {
|
if (record) {
|
||||||
const observable = record.observe();
|
const observable = record.observe() as Observable<TSubscriptionModel | TUserModel>;
|
||||||
this.subscription = observable.subscribe((r: any) => {
|
this.subscription = observable.subscribe(r => {
|
||||||
const { avatarETag } = r;
|
const { avatarETag } = r;
|
||||||
if (this.mounted) {
|
if (this.mounted) {
|
||||||
this.setState({ avatarETag });
|
this.setState({ avatarETag });
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Storyshots BackgroundContainer basic 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessibilityIgnoresInvertColors\\":true,\\"style\\":{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\",\\"position\\":\\"absolute\\"}},\\"children\\":[{\\"type\\":\\"Image\\",\\"props\\":{\\"source\\":{\\"uri\\":\\"message_empty_light\\"},\\"style\\":[{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\"},null]},\\"children\\":null}]}]}"`;
|
||||||
|
|
||||||
|
exports[`Storyshots BackgroundContainer black theme - loading 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessibilityIgnoresInvertColors\\":true,\\"style\\":{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\",\\"position\\":\\"absolute\\"}},\\"children\\":[{\\"type\\":\\"Image\\",\\"props\\":{\\"source\\":{\\"uri\\":\\"message_empty_black\\"},\\"style\\":[{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\"},null]},\\"children\\":null}]},{\\"type\\":\\"ActivityIndicator\\",\\"props\\":{\\"animating\\":true,\\"color\\":\\"#f9f9f9\\",\\"hidesWhenStopped\\":true,\\"size\\":\\"small\\",\\"style\\":{\\"position\\":\\"absolute\\",\\"top\\":60,\\"left\\":0,\\"right\\":0,\\"fontSize\\":16,\\"paddingHorizontal\\":24,\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}},\\"children\\":null}]}"`;
|
||||||
|
|
||||||
|
exports[`Storyshots BackgroundContainer black theme - text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessibilityIgnoresInvertColors\\":true,\\"style\\":{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\",\\"position\\":\\"absolute\\"}},\\"children\\":[{\\"type\\":\\"Image\\",\\"props\\":{\\"source\\":{\\"uri\\":\\"message_empty_black\\"},\\"style\\":[{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\"},null]},\\"children\\":null}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"position\\":\\"absolute\\",\\"top\\":60,\\"left\\":0,\\"right\\":0,\\"fontSize\\":16,\\"paddingHorizontal\\":24,\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#f9f9f9\\"}]},\\"children\\":[\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\"]}]}"`;
|
||||||
|
|
||||||
|
exports[`Storyshots BackgroundContainer dark theme - loading 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessibilityIgnoresInvertColors\\":true,\\"style\\":{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\",\\"position\\":\\"absolute\\"}},\\"children\\":[{\\"type\\":\\"Image\\",\\"props\\":{\\"source\\":{\\"uri\\":\\"message_empty_dark\\"},\\"style\\":[{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\"},null]},\\"children\\":null}]},{\\"type\\":\\"ActivityIndicator\\",\\"props\\":{\\"animating\\":true,\\"color\\":\\"#f9f9f9\\",\\"hidesWhenStopped\\":true,\\"size\\":\\"small\\",\\"style\\":{\\"position\\":\\"absolute\\",\\"top\\":60,\\"left\\":0,\\"right\\":0,\\"fontSize\\":16,\\"paddingHorizontal\\":24,\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}},\\"children\\":null}]}"`;
|
||||||
|
|
||||||
|
exports[`Storyshots BackgroundContainer dark theme - text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessibilityIgnoresInvertColors\\":true,\\"style\\":{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\",\\"position\\":\\"absolute\\"}},\\"children\\":[{\\"type\\":\\"Image\\",\\"props\\":{\\"source\\":{\\"uri\\":\\"message_empty_dark\\"},\\"style\\":[{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\"},null]},\\"children\\":null}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"position\\":\\"absolute\\",\\"top\\":60,\\"left\\":0,\\"right\\":0,\\"fontSize\\":16,\\"paddingHorizontal\\":24,\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#f9f9f9\\"}]},\\"children\\":[\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\"]}]}"`;
|
||||||
|
|
||||||
|
exports[`Storyshots BackgroundContainer loading 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessibilityIgnoresInvertColors\\":true,\\"style\\":{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\",\\"position\\":\\"absolute\\"}},\\"children\\":[{\\"type\\":\\"Image\\",\\"props\\":{\\"source\\":{\\"uri\\":\\"message_empty_light\\"},\\"style\\":[{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\"},null]},\\"children\\":null}]},{\\"type\\":\\"ActivityIndicator\\",\\"props\\":{\\"animating\\":true,\\"color\\":\\"#6C727A\\",\\"hidesWhenStopped\\":true,\\"size\\":\\"small\\",\\"style\\":{\\"position\\":\\"absolute\\",\\"top\\":60,\\"left\\":0,\\"right\\":0,\\"fontSize\\":16,\\"paddingHorizontal\\":24,\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}},\\"children\\":null}]}"`;
|
||||||
|
|
||||||
|
exports[`Storyshots BackgroundContainer long text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessibilityIgnoresInvertColors\\":true,\\"style\\":{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\",\\"position\\":\\"absolute\\"}},\\"children\\":[{\\"type\\":\\"Image\\",\\"props\\":{\\"source\\":{\\"uri\\":\\"message_empty_light\\"},\\"style\\":[{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\"},null]},\\"children\\":null}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"position\\":\\"absolute\\",\\"top\\":60,\\"left\\":0,\\"right\\":0,\\"fontSize\\":16,\\"paddingHorizontal\\":24,\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#6C727A\\"}]},\\"children\\":[\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\"]}]}"`;
|
||||||
|
|
||||||
|
exports[`Storyshots BackgroundContainer text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"accessibilityIgnoresInvertColors\\":true,\\"style\\":{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\",\\"position\\":\\"absolute\\"}},\\"children\\":[{\\"type\\":\\"Image\\",\\"props\\":{\\"source\\":{\\"uri\\":\\"message_empty_light\\"},\\"style\\":[{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},{\\"width\\":\\"100%\\",\\"height\\":\\"100%\\"},null]},\\"children\\":null}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"position\\":\\"absolute\\",\\"top\\":60,\\"left\\":0,\\"right\\":0,\\"fontSize\\":16,\\"paddingHorizontal\\":24,\\"textAlign\\":\\"center\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#6C727A\\"}]},\\"children\\":[\\"Text here\\"]}]}"`;
|
|
@ -35,7 +35,7 @@ const styles = StyleSheet.create({
|
||||||
const BackgroundContainer = ({ theme, text, loading }: IBackgroundContainer) => (
|
const BackgroundContainer = ({ theme, text, loading }: IBackgroundContainer) => (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<ImageBackground source={{ uri: `message_empty_${theme}` }} style={styles.image} />
|
<ImageBackground source={{ uri: `message_empty_${theme}` }} style={styles.image} />
|
||||||
{text ? <Text style={[styles.text, { color: themes[theme!].auxiliaryTintColor }]}>{text}</Text> : null}
|
{text && !loading ? <Text style={[styles.text, { color: themes[theme!].auxiliaryTintColor }]}>{text}</Text> : null}
|
||||||
{loading ? <ActivityIndicator style={styles.text} color={themes[theme!].auxiliaryTintColor} /> : null}
|
{loading ? <ActivityIndicator style={styles.text} color={themes[theme!].auxiliaryTintColor} /> : null}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
|
@ -36,7 +36,7 @@ interface IEmojiPickerProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IEmojiPickerState {
|
interface IEmojiPickerState {
|
||||||
frequentlyUsed: [];
|
frequentlyUsed: (string | { content?: string; extension?: string; isCustom: boolean })[];
|
||||||
customEmojis: any;
|
customEmojis: any;
|
||||||
show: boolean;
|
show: boolean;
|
||||||
width: number | null;
|
width: number | null;
|
||||||
|
@ -114,7 +114,7 @@ class EmojiPicker extends Component<IEmojiPickerProps, IEmojiPickerState> {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.action(async () => {
|
await db.write(async () => {
|
||||||
if (freqEmojiRecord) {
|
if (freqEmojiRecord) {
|
||||||
await freqEmojiRecord.update((f: any) => {
|
await freqEmojiRecord.update((f: any) => {
|
||||||
f.count += 1;
|
f.count += 1;
|
||||||
|
@ -132,8 +132,8 @@ class EmojiPicker extends Component<IEmojiPickerProps, IEmojiPickerState> {
|
||||||
updateFrequentlyUsed = async () => {
|
updateFrequentlyUsed = async () => {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const frequentlyUsedRecords = await db.get('frequently_used_emojis').query().fetch();
|
const frequentlyUsedRecords = await db.get('frequently_used_emojis').query().fetch();
|
||||||
let frequentlyUsed: any = orderBy(frequentlyUsedRecords, ['count'], ['desc']);
|
const frequentlyUsedOrdered = orderBy(frequentlyUsedRecords, ['count'], ['desc']);
|
||||||
frequentlyUsed = frequentlyUsed.map((item: IEmoji) => {
|
const frequentlyUsed = frequentlyUsedOrdered.map(item => {
|
||||||
if (item.isCustom) {
|
if (item.isCustom) {
|
||||||
return { content: item.content, extension: item.extension, isCustom: item.isCustom };
|
return { content: item.content, extension: item.extension, isCustom: item.isCustom };
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import database from '../../lib/database';
|
||||||
import { Button } from '../ActionSheet';
|
import { Button } from '../ActionSheet';
|
||||||
import { useDimensions } from '../../dimensions';
|
import { useDimensions } from '../../dimensions';
|
||||||
import sharedStyles from '../../views/Styles';
|
import sharedStyles from '../../views/Styles';
|
||||||
|
import { TFrequentlyUsedEmojiModel } from '../../definitions/IFrequentlyUsedEmoji';
|
||||||
import { IEmoji } from '../EmojiPicker/interfaces';
|
import { IEmoji } from '../EmojiPicker/interfaces';
|
||||||
|
|
||||||
interface IHeader {
|
interface IHeader {
|
||||||
|
@ -90,14 +91,14 @@ const HeaderFooter = React.memo(({ onReaction, theme }: THeaderFooter) => (
|
||||||
));
|
));
|
||||||
|
|
||||||
const Header = React.memo(({ handleReaction, server, message, isMasterDetail, theme }: IHeader) => {
|
const Header = React.memo(({ handleReaction, server, message, isMasterDetail, theme }: IHeader) => {
|
||||||
const [items, setItems] = useState([]);
|
const [items, setItems] = useState<(TFrequentlyUsedEmojiModel | string)[]>([]);
|
||||||
const { width, height }: any = useDimensions();
|
const { width, height }: any = useDimensions();
|
||||||
|
|
||||||
const setEmojis = async () => {
|
const setEmojis = async () => {
|
||||||
try {
|
try {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const freqEmojiCollection = db.get('frequently_used_emojis');
|
const freqEmojiCollection = db.get('frequently_used_emojis');
|
||||||
let freqEmojis = await freqEmojiCollection.query().fetch();
|
let freqEmojis: (TFrequentlyUsedEmojiModel | string)[] = await freqEmojiCollection.query().fetch();
|
||||||
|
|
||||||
const isLandscape = width > height;
|
const isLandscape = width > height;
|
||||||
const size = (isLandscape || isMasterDetail ? width / 2 : width) - CONTAINER_MARGIN * 2;
|
const size = (isLandscape || isMasterDetail ? width / 2 : width) - CONTAINER_MARGIN * 2;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { showConfirmationAlert } from '../../utils/info';
|
||||||
import { useActionSheet } from '../ActionSheet';
|
import { useActionSheet } from '../ActionSheet';
|
||||||
import Header, { HEADER_HEIGHT } from './Header';
|
import Header, { HEADER_HEIGHT } from './Header';
|
||||||
import events from '../../utils/log/events';
|
import events from '../../utils/log/events';
|
||||||
|
import { TMessageModel } from '../../definitions/IMessage';
|
||||||
|
|
||||||
interface IMessageActions {
|
interface IMessageActions {
|
||||||
room: {
|
room: {
|
||||||
|
@ -182,9 +183,9 @@ const MessageActions = React.memo(
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
const subCollection = db.get('subscriptions');
|
const subCollection = db.get('subscriptions');
|
||||||
const subRecord = await subCollection.find(rid);
|
const subRecord = await subCollection.find(rid);
|
||||||
await db.action(async () => {
|
await db.write(async () => {
|
||||||
try {
|
try {
|
||||||
await subRecord.update((sub: any) => (sub.lastOpen = ts));
|
await subRecord.update(sub => (sub.lastOpen = ts));
|
||||||
} catch {
|
} catch {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -269,11 +270,11 @@ const MessageActions = React.memo(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleToggleTranslation = async (message: any) => {
|
const handleToggleTranslation = async (message: TMessageModel) => {
|
||||||
try {
|
try {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
await db.action(async () => {
|
await db.write(async () => {
|
||||||
await message.update((m: any) => {
|
await message.update(m => {
|
||||||
m.autoTranslate = !m.autoTranslate;
|
m.autoTranslate = !m.autoTranslate;
|
||||||
m._updatedAt = new Date();
|
m._updatedAt = new Date();
|
||||||
});
|
});
|
||||||
|
@ -320,7 +321,7 @@ const MessageActions = React.memo(
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOptions = (message: any) => {
|
const getOptions = (message: TMessageModel) => {
|
||||||
let options: any = [];
|
let options: any = [];
|
||||||
|
|
||||||
// Reply
|
// Reply
|
||||||
|
@ -446,7 +447,7 @@ const MessageActions = React.memo(
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
const showMessageActions = async (message: any) => {
|
const showMessageActions = async (message: TMessageModel) => {
|
||||||
logEvent(events.ROOM_SHOW_MSG_ACTIONS);
|
logEvent(events.ROOM_SHOW_MSG_ACTIONS);
|
||||||
await getPermissions();
|
await getPermissions();
|
||||||
showActionSheet({
|
showActionSheet({
|
||||||
|
|
|
@ -36,7 +36,7 @@ const MessageErrorActions = forwardRef(({ tmid }: any, ref): any => {
|
||||||
try {
|
try {
|
||||||
// Find the thread header and update it
|
// Find the thread header and update it
|
||||||
const msg = await msgCollection.find(tmid);
|
const msg = await msgCollection.find(tmid);
|
||||||
if (msg.tcount <= 1) {
|
if (msg?.tcount && msg.tcount <= 1) {
|
||||||
deleteBatch.push(
|
deleteBatch.push(
|
||||||
msg.prepareUpdate((m: any) => {
|
msg.prepareUpdate((m: any) => {
|
||||||
m.tcount = null;
|
m.tcount = null;
|
||||||
|
@ -62,7 +62,7 @@ const MessageErrorActions = forwardRef(({ tmid }: any, ref): any => {
|
||||||
// Do nothing: message not found
|
// Do nothing: message not found
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await db.action(async () => {
|
await db.write(async () => {
|
||||||
await db.batch(...deleteBatch);
|
await db.batch(...deleteBatch);
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,11 @@
|
||||||
|
import { dequal } from 'dequal';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { dequal } from 'dequal';
|
|
||||||
|
|
||||||
import RoomHeader from './RoomHeader';
|
import { IApplicationState } from '../../definitions';
|
||||||
import { withDimensions } from '../../dimensions';
|
import { withDimensions } from '../../dimensions';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
|
import RoomHeader from './RoomHeader';
|
||||||
|
|
||||||
interface IRoomHeaderContainerProps {
|
interface IRoomHeaderContainerProps {
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -122,8 +123,8 @@ class RoomHeaderContainer extends Component<IRoomHeaderContainerProps, any> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = (state: any, ownProps: any) => {
|
const mapStateToProps = (state: IApplicationState, ownProps: any) => {
|
||||||
let statusText;
|
let statusText = '';
|
||||||
let status = 'offline';
|
let status = 'offline';
|
||||||
const { roomUserId, type, visitor = {}, tmid } = ownProps;
|
const { roomUserId, type, visitor = {}, tmid } = ownProps;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyleSheet, View } from 'react-native';
|
import { StyleSheet, View } from 'react-native';
|
||||||
|
|
||||||
import { withTheme } from '../theme';
|
import I18n from '../i18n';
|
||||||
|
import { useTheme } from '../theme';
|
||||||
import sharedStyles from '../views/Styles';
|
import sharedStyles from '../views/Styles';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import TextInput from '../presentation/TextInput';
|
import TextInput from '../presentation/TextInput';
|
||||||
|
@ -19,14 +20,13 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
interface ISearchHeader {
|
interface ISearchHeaderProps {
|
||||||
theme?: string;
|
|
||||||
onSearchChangeText?: (text: string) => void;
|
onSearchChangeText?: (text: string) => void;
|
||||||
|
testID: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: it might be useful to refactor this component for reusage
|
const SearchHeader = ({ onSearchChangeText, testID }: ISearchHeaderProps): JSX.Element => {
|
||||||
const SearchHeader = ({ theme, onSearchChangeText }: ISearchHeader) => {
|
const { theme } = useTheme();
|
||||||
const titleColorStyle = { color: themes[theme!].headerTitleColor };
|
|
||||||
const isLight = theme === 'light';
|
const isLight = theme === 'light';
|
||||||
const { isLandscape } = useOrientation();
|
const { isLandscape } = useOrientation();
|
||||||
const scale = isIOS && isLandscape && !isTablet ? 0.8 : 1;
|
const scale = isIOS && isLandscape && !isTablet ? 0.8 : 1;
|
||||||
|
@ -36,14 +36,14 @@ const SearchHeader = ({ theme, onSearchChangeText }: ISearchHeader) => {
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<TextInput
|
<TextInput
|
||||||
autoFocus
|
autoFocus
|
||||||
style={[styles.title, isLight && titleColorStyle, { fontSize: titleFontSize }]}
|
style={[styles.title, isLight && { color: themes[theme].headerTitleColor }, { fontSize: titleFontSize }]}
|
||||||
placeholder='Search'
|
placeholder={I18n.t('Search')}
|
||||||
onChangeText={onSearchChangeText}
|
onChangeText={onSearchChangeText}
|
||||||
theme={theme!}
|
theme={theme}
|
||||||
testID='thread-messages-view-search-header'
|
testID={testID}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withTheme(SearchHeader);
|
export default SearchHeader;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Touchable from 'react-native-platform-touchable';
|
||||||
import { CustomIcon } from '../lib/Icons';
|
import { CustomIcon } from '../lib/Icons';
|
||||||
import { themes } from '../constants/colors';
|
import { themes } from '../constants/colors';
|
||||||
import sharedStyles from '../views/Styles';
|
import sharedStyles from '../views/Styles';
|
||||||
import { withTheme } from '../theme';
|
import { useTheme } from '../theme';
|
||||||
import { TThreadModel } from '../definitions/IThread';
|
import { TThreadModel } from '../definitions/IThread';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
@ -48,12 +48,12 @@ interface IThreadDetails {
|
||||||
badgeColor?: string;
|
badgeColor?: string;
|
||||||
toggleFollowThread: Function;
|
toggleFollowThread: Function;
|
||||||
style: ViewStyle;
|
style: ViewStyle;
|
||||||
theme?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ThreadDetails = ({ item, user, badgeColor, toggleFollowThread, style, theme }: IThreadDetails) => {
|
const ThreadDetails = ({ item, user, badgeColor, toggleFollowThread, style }: IThreadDetails): JSX.Element => {
|
||||||
|
const { theme } = useTheme();
|
||||||
let { tcount } = item;
|
let { tcount } = item;
|
||||||
if (tcount! >= 1000) {
|
if (tcount && tcount >= 1000) {
|
||||||
tcount = '+999';
|
tcount = '+999';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,6 @@ const ThreadDetails = ({ item, user, badgeColor, toggleFollowThread, style, them
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.badgeContainer}>
|
<View style={styles.badgeContainer}>
|
||||||
{badgeColor ? <View style={[styles.badge, { backgroundColor: badgeColor }]} /> : null}
|
{badgeColor ? <View style={[styles.badge, { backgroundColor: badgeColor }]} /> : null}
|
||||||
<Touchable onPress={() => toggleFollowThread?.(isFollowing, item.id)}>
|
<Touchable onPress={() => toggleFollowThread?.(isFollowing, item.id)}>
|
||||||
|
@ -96,4 +95,4 @@ const ThreadDetails = ({ item, user, badgeColor, toggleFollowThread, style, them
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withTheme(ThreadDetails);
|
export default ThreadDetails;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Storyshots Text Input Short and Long Text 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"paddingHorizontal\\":14}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"marginBottom\\":10},null]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"marginBottom\\":10,\\"fontSize\\":14,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\"},{\\"color\\":\\"#0d0e12\\"},null]},\\"children\\":[\\"Short Text\\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"position\\":\\"relative\\"}},\\"children\\":[{\\"type\\":\\"TextInput\\",\\"props\\":{\\"allowFontScaling\\":true,\\"rejectResponderTermination\\":true,\\"underlineColorAndroid\\":\\"transparent\\",\\"style\\":[{\\"color\\":\\"#0d0e12\\"},[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\",\\"height\\":48,\\"fontSize\\":16,\\"padding\\":14,\\"borderWidth\\":0.5,\\"borderRadius\\":2},null,null,{\\"backgroundColor\\":\\"#ffffff\\",\\"borderColor\\":\\"#cbcbcc\\",\\"color\\":\\"#0d0e12\\"},null,null],{\\"textAlign\\":\\"auto\\"}],\\"placeholderTextColor\\":\\"#9ca2a8\\",\\"keyboardAppearance\\":\\"light\\",\\"autoCorrect\\":false,\\"autoCapitalize\\":\\"none\\",\\"accessibilityLabel\\":\\"placeholder\\",\\"placeholder\\":\\"placeholder\\",\\"value\\":\\"Rocket.Chat\\"},\\"children\\":null}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"marginBottom\\":10},null]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"marginBottom\\":10,\\"fontSize\\":14,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\"},{\\"color\\":\\"#0d0e12\\"},null]},\\"children\\":[\\"Long Text\\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"position\\":\\"relative\\"}},\\"children\\":[{\\"type\\":\\"TextInput\\",\\"props\\":{\\"allowFontScaling\\":true,\\"rejectResponderTermination\\":true,\\"underlineColorAndroid\\":\\"transparent\\",\\"style\\":[{\\"color\\":\\"#0d0e12\\"},[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\",\\"height\\":48,\\"fontSize\\":16,\\"padding\\":14,\\"borderWidth\\":0.5,\\"borderRadius\\":2},null,null,{\\"backgroundColor\\":\\"#ffffff\\",\\"borderColor\\":\\"#cbcbcc\\",\\"color\\":\\"#0d0e12\\"},null,null],{\\"textAlign\\":\\"auto\\"}],\\"placeholderTextColor\\":\\"#9ca2a8\\",\\"keyboardAppearance\\":\\"light\\",\\"autoCorrect\\":false,\\"autoCapitalize\\":\\"none\\",\\"accessibilityLabel\\":\\"placeholder\\",\\"placeholder\\":\\"placeholder\\",\\"value\\":\\"https://open.rocket.chat/images/logo/android-chrome-512x512.png\\"},\\"children\\":null}]}]}]}"`;
|
|
@ -25,7 +25,7 @@ import { isValidURL } from '../../utils/url';
|
||||||
import NewMarkdown from './new';
|
import NewMarkdown from './new';
|
||||||
|
|
||||||
interface IMarkdownProps {
|
interface IMarkdownProps {
|
||||||
msg: string;
|
msg?: string;
|
||||||
md: MarkdownAST;
|
md: MarkdownAST;
|
||||||
mentions: UserMention[];
|
mentions: UserMention[];
|
||||||
getCustomEmoji: Function;
|
getCustomEmoji: Function;
|
||||||
|
|
|
@ -182,7 +182,7 @@ const Fields = React.memo(
|
||||||
<Text style={[styles.fieldTitle, { color: themes[theme].bodyText }]}>{field.title}</Text>
|
<Text style={[styles.fieldTitle, { color: themes[theme].bodyText }]}>{field.title}</Text>
|
||||||
{/* @ts-ignore*/}
|
{/* @ts-ignore*/}
|
||||||
<Markdown
|
<Markdown
|
||||||
msg={field.value!}
|
msg={field?.value || ''}
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl}
|
||||||
username={user.username}
|
username={user.username}
|
||||||
getCustomEmoji={getCustomEmoji}
|
getCustomEmoji={getCustomEmoji}
|
||||||
|
|
|
@ -24,7 +24,6 @@ const Thread = React.memo(
|
||||||
item={{
|
item={{
|
||||||
tcount,
|
tcount,
|
||||||
replies,
|
replies,
|
||||||
tlm,
|
|
||||||
id
|
id
|
||||||
}}
|
}}
|
||||||
user={user}
|
user={user}
|
||||||
|
|
|
@ -147,6 +147,12 @@ class MessageContainer extends React.Component<IMessageContainerProps> {
|
||||||
if ((item.tlm || item.tmid) && !isThreadRoom) {
|
if ((item.tlm || item.tmid) && !isThreadRoom) {
|
||||||
this.onThreadPress();
|
this.onThreadPress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { onDiscussionPress } = this.props;
|
||||||
|
|
||||||
|
if (onDiscussionPress) {
|
||||||
|
onDiscussionPress(item);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
300,
|
300,
|
||||||
true
|
true
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { MarkdownAST } from '@rocket.chat/message-parser';
|
import { MarkdownAST } from '@rocket.chat/message-parser';
|
||||||
|
|
||||||
|
export type TMessageType = 'discussion-created' | 'jitsi_call_started';
|
||||||
|
|
||||||
export interface IMessageAttachments {
|
export interface IMessageAttachments {
|
||||||
attachments: any;
|
attachments: any;
|
||||||
timeFormat: string;
|
timeFormat: string;
|
||||||
|
@ -101,7 +103,7 @@ export interface IMessageThread {
|
||||||
msg: string;
|
msg: string;
|
||||||
tcount: number;
|
tcount: number;
|
||||||
theme: string;
|
theme: string;
|
||||||
tlm: string;
|
tlm: Date;
|
||||||
isThreadRoom: boolean;
|
isThreadRoom: boolean;
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +142,7 @@ export interface IMessageInner
|
||||||
IMessageThread,
|
IMessageThread,
|
||||||
IMessageAttachments,
|
IMessageAttachments,
|
||||||
IMessageBroadcast {
|
IMessageBroadcast {
|
||||||
type: string;
|
type: TMessageType;
|
||||||
blocks: [];
|
blocks: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { TMessageModel } from '../../definitions/IMessage';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { DISCUSSION } from './constants';
|
import { DISCUSSION } from './constants';
|
||||||
|
|
||||||
|
@ -149,7 +150,7 @@ export const getInfoMessage = ({ type, role, msg, author }: TInfoMessage) => {
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getMessageTranslation = (message: { translations: any }, autoTranslateLanguage: string) => {
|
export const getMessageTranslation = (message: TMessageModel, autoTranslateLanguage: string) => {
|
||||||
if (!autoTranslateLanguage) {
|
if (!autoTranslateLanguage) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,4 @@ export interface IFrequentlyUsedEmoji {
|
||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TFrequentlyUsedEmoji = IFrequentlyUsedEmoji & Model;
|
export type TFrequentlyUsedEmojiModel = IFrequentlyUsedEmoji & Model;
|
||||||
|
|
|
@ -15,4 +15,4 @@ export interface ILoggedUser {
|
||||||
enableMessageParserEarlyAdoption?: boolean;
|
enableMessageParserEarlyAdoption?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TLoggedUser = ILoggedUser & Model;
|
export type TLoggedUserModel = ILoggedUser & Model;
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { SortBy, DisplayMode } from '../constants/constantDisplayMode';
|
||||||
|
|
||||||
|
export interface IPreferences {
|
||||||
|
sortBy: SortBy;
|
||||||
|
groupByType: boolean;
|
||||||
|
showFavorites: boolean;
|
||||||
|
showUnread: boolean;
|
||||||
|
showAvatar: boolean;
|
||||||
|
displayMode: DisplayMode;
|
||||||
|
}
|
|
@ -7,4 +7,4 @@ export interface IServerHistory {
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TServerHistory = IServerHistory & Model;
|
export type TServerHistoryModel = IServerHistory & Model;
|
||||||
|
|
|
@ -79,8 +79,6 @@ export interface ISubscription {
|
||||||
avatarETag?: string;
|
avatarETag?: string;
|
||||||
teamId?: string;
|
teamId?: string;
|
||||||
teamMain?: boolean;
|
teamMain?: boolean;
|
||||||
search?: boolean;
|
|
||||||
username?: string;
|
|
||||||
// https://nozbe.github.io/WatermelonDB/Relation.html#relation-api
|
// https://nozbe.github.io/WatermelonDB/Relation.html#relation-api
|
||||||
messages: Relation<TMessageModel>;
|
messages: Relation<TMessageModel>;
|
||||||
threads: Relation<TThreadModel>;
|
threads: Relation<TThreadModel>;
|
||||||
|
|
|
@ -43,7 +43,7 @@ export interface IThread {
|
||||||
id: string;
|
id: string;
|
||||||
msg?: string;
|
msg?: string;
|
||||||
t?: SubscriptionType;
|
t?: SubscriptionType;
|
||||||
rid?: string;
|
rid: string;
|
||||||
_updatedAt?: Date;
|
_updatedAt?: Date;
|
||||||
ts?: Date;
|
ts?: Date;
|
||||||
u?: IUserMessage;
|
u?: IUserMessage;
|
||||||
|
@ -61,10 +61,10 @@ export interface IThread {
|
||||||
reactions?: IReaction[];
|
reactions?: IReaction[];
|
||||||
role?: string;
|
role?: string;
|
||||||
drid?: string;
|
drid?: string;
|
||||||
dcount?: number;
|
dcount?: number | string;
|
||||||
dlm?: number;
|
dlm?: number;
|
||||||
tmid?: string;
|
tmid?: string;
|
||||||
tcount: number | string;
|
tcount?: number | string;
|
||||||
tlm?: string;
|
tlm?: string;
|
||||||
replies?: string[];
|
replies?: string[];
|
||||||
mentions?: IUserMention[];
|
mentions?: IUserMention[];
|
||||||
|
|
|
@ -3,11 +3,24 @@ import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
import { Dispatch } from 'redux';
|
import { Dispatch } from 'redux';
|
||||||
|
|
||||||
export * from './IAttachment';
|
export * from './IAttachment';
|
||||||
export * from './IMessage';
|
|
||||||
export * from './INotification';
|
export * from './INotification';
|
||||||
export * from './IRoom';
|
export * from './IPreferences';
|
||||||
export * from './IServer';
|
|
||||||
export * from './ISubscription';
|
export * from './ISubscription';
|
||||||
|
export * from './IRoom';
|
||||||
|
export * from './IMessage';
|
||||||
|
export * from './IThread';
|
||||||
|
export * from './IThreadMessage';
|
||||||
|
export * from './ICustomEmoji';
|
||||||
|
export * from './IFrequentlyUsedEmoji';
|
||||||
|
export * from './IUpload';
|
||||||
|
export * from './ISettings';
|
||||||
|
export * from './IRole';
|
||||||
|
export * from './IPermission';
|
||||||
|
export * from './ISlashCommand';
|
||||||
|
export * from './IUser';
|
||||||
|
export * from './IServer';
|
||||||
|
export * from './ILoggedUser';
|
||||||
|
export * from './IServerHistory';
|
||||||
|
|
||||||
export interface IBaseScreen<T extends Record<string, object | undefined>, S extends string> {
|
export interface IBaseScreen<T extends Record<string, object | undefined>, S extends string> {
|
||||||
navigation: StackNavigationProp<T, S>;
|
navigation: StackNavigationProp<T, S>;
|
||||||
|
@ -17,3 +30,4 @@ export interface IBaseScreen<T extends Record<string, object | undefined>, S ext
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './redux';
|
export * from './redux';
|
||||||
|
export * from './redux/TRootEnum';
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
export enum RootEnum {
|
||||||
|
ROOT_OUTSIDE = 'outside',
|
||||||
|
ROOT_INSIDE = 'inside',
|
||||||
|
ROOT_LOADING = 'loading',
|
||||||
|
ROOT_SET_USERNAME = 'setUsername'
|
||||||
|
}
|
|
@ -1,31 +1,67 @@
|
||||||
import { TActionSelectedUsers } from '../../actions/selectedUsers';
|
// ACTIONS
|
||||||
import { TActionActiveUsers } from '../../actions/activeUsers';
|
import { TActionActiveUsers } from '../../actions/activeUsers';
|
||||||
|
import { TActionApp } from '../../actions/app';
|
||||||
|
import { TActionCreateChannel } from '../../actions/createChannel';
|
||||||
|
import { TActionCreateDiscussion } from '../../actions/createDiscussion';
|
||||||
|
import { TActionCustomEmojis } from '../../actions/customEmojis';
|
||||||
|
import { TActionEncryption } from '../../actions/encryption';
|
||||||
|
import { TActionInviteLinks } from '../../actions/inviteLinks';
|
||||||
|
import { IActionRoles } from '../../actions/roles';
|
||||||
|
import { TActionSelectedUsers } from '../../actions/selectedUsers';
|
||||||
|
import { TActionServer } from '../../actions/server';
|
||||||
|
import { IActionSettings } from '../../actions/settings';
|
||||||
|
import { TActionsShare } from '../../actions/share';
|
||||||
|
import { TActionSortPreferences } from '../../actions/sortPreferences';
|
||||||
|
import { TActionUserTyping } from '../../actions/usersTyping';
|
||||||
// REDUCERS
|
// REDUCERS
|
||||||
import { IActiveUsers } from '../../reducers/activeUsers';
|
import { IActiveUsers } from '../../reducers/activeUsers';
|
||||||
|
import { IApp } from '../../reducers/app';
|
||||||
|
import { IConnect } from '../../reducers/connect';
|
||||||
|
import { ICreateChannel } from '../../reducers/createChannel';
|
||||||
|
import { ICreateDiscussion } from '../../reducers/createDiscussion';
|
||||||
|
import { IEncryption } from '../../reducers/encryption';
|
||||||
|
import { IInviteLinks } from '../../reducers/inviteLinks';
|
||||||
|
import { IRoles } from '../../reducers/roles';
|
||||||
import { ISelectedUsers } from '../../reducers/selectedUsers';
|
import { ISelectedUsers } from '../../reducers/selectedUsers';
|
||||||
|
import { IServer } from '../../reducers/server';
|
||||||
|
import { ISettings } from '../../reducers/settings';
|
||||||
|
import { IShare } from '../../reducers/share';
|
||||||
|
|
||||||
export interface IApplicationState {
|
export interface IApplicationState {
|
||||||
settings: any;
|
settings: ISettings;
|
||||||
login: any;
|
login: any;
|
||||||
meteor: any;
|
meteor: IConnect;
|
||||||
server: any;
|
server: IServer;
|
||||||
selectedUsers: ISelectedUsers;
|
selectedUsers: ISelectedUsers;
|
||||||
createChannel: any;
|
app: IApp;
|
||||||
app: any;
|
createChannel: ICreateChannel;
|
||||||
room: any;
|
room: any;
|
||||||
rooms: any;
|
rooms: any;
|
||||||
sortPreferences: any;
|
sortPreferences: any;
|
||||||
share: any;
|
share: IShare;
|
||||||
customEmojis: any;
|
customEmojis: any;
|
||||||
activeUsers: IActiveUsers;
|
activeUsers: IActiveUsers;
|
||||||
usersTyping: any;
|
usersTyping: any;
|
||||||
inviteLinks: any;
|
inviteLinks: IInviteLinks;
|
||||||
createDiscussion: any;
|
createDiscussion: ICreateDiscussion;
|
||||||
inquiry: any;
|
inquiry: any;
|
||||||
enterpriseModules: any;
|
enterpriseModules: any;
|
||||||
encryption: any;
|
encryption: IEncryption;
|
||||||
permissions: any;
|
permissions: any;
|
||||||
roles: any;
|
roles: IRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TApplicationActions = TActionActiveUsers & TActionSelectedUsers;
|
export type TApplicationActions = TActionActiveUsers &
|
||||||
|
TActionSelectedUsers &
|
||||||
|
TActionCustomEmojis &
|
||||||
|
TActionInviteLinks &
|
||||||
|
IActionRoles &
|
||||||
|
IActionSettings &
|
||||||
|
TActionEncryption &
|
||||||
|
TActionSortPreferences &
|
||||||
|
TActionUserTyping &
|
||||||
|
TActionCreateDiscussion&
|
||||||
|
TActionCreateChannel &
|
||||||
|
TActionsShare &
|
||||||
|
TActionServer &
|
||||||
|
TActionApp;
|
||||||
|
|
|
@ -775,6 +775,7 @@
|
||||||
"creating_discussion": "creating discussion",
|
"creating_discussion": "creating discussion",
|
||||||
"Canned_Responses": "Canned Responses",
|
"Canned_Responses": "Canned Responses",
|
||||||
"No_match_found": "No match found.",
|
"No_match_found": "No match found.",
|
||||||
|
"No_discussions": "No discussions",
|
||||||
"Check_canned_responses": "Check on canned responses.",
|
"Check_canned_responses": "Check on canned responses.",
|
||||||
"Searching": "Searching",
|
"Searching": "Searching",
|
||||||
"Use": "Use",
|
"Use": "Use",
|
||||||
|
|
|
@ -25,6 +25,7 @@ import serversSchema from './schema/servers';
|
||||||
import appSchema from './schema/app';
|
import appSchema from './schema/app';
|
||||||
import migrations from './model/migrations';
|
import migrations from './model/migrations';
|
||||||
import serversMigrations from './model/servers/migrations';
|
import serversMigrations from './model/servers/migrations';
|
||||||
|
import { TAppDatabase, TServerDatabase } from './interfaces';
|
||||||
|
|
||||||
const appGroupPath = isIOS ? appGroup.path : '';
|
const appGroupPath = isIOS ? appGroup.path : '';
|
||||||
|
|
||||||
|
@ -32,9 +33,9 @@ if (__DEV__ && isIOS) {
|
||||||
console.log(appGroupPath);
|
console.log(appGroupPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDatabasePath = name => `${appGroupPath}${name}${isOfficial ? '' : '-experimental'}.db`;
|
const getDatabasePath = (name: string) => `${appGroupPath}${name}${isOfficial ? '' : '-experimental'}.db`;
|
||||||
|
|
||||||
export const getDatabase = (database = '') => {
|
export const getDatabase = (database = ''): Database => {
|
||||||
const path = database.replace(/(^\w+:|^)\/\//, '').replace(/\//g, '.');
|
const path = database.replace(/(^\w+:|^)\/\//, '').replace(/\//g, '.');
|
||||||
const dbName = getDatabasePath(path);
|
const dbName = getDatabasePath(path);
|
||||||
|
|
||||||
|
@ -64,8 +65,14 @@ export const getDatabase = (database = '') => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface IDatabases {
|
||||||
|
shareDB?: TAppDatabase;
|
||||||
|
serversDB: TServerDatabase;
|
||||||
|
activeDB?: TAppDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
class DB {
|
class DB {
|
||||||
databases = {
|
databases: IDatabases = {
|
||||||
serversDB: new Database({
|
serversDB: new Database({
|
||||||
adapter: new SQLiteAdapter({
|
adapter: new SQLiteAdapter({
|
||||||
dbName: getDatabasePath('default'),
|
dbName: getDatabasePath('default'),
|
||||||
|
@ -73,11 +80,12 @@ class DB {
|
||||||
migrations: serversMigrations
|
migrations: serversMigrations
|
||||||
}),
|
}),
|
||||||
modelClasses: [Server, LoggedUser, ServersHistory]
|
modelClasses: [Server, LoggedUser, ServersHistory]
|
||||||
})
|
}) as TServerDatabase
|
||||||
};
|
};
|
||||||
|
|
||||||
get active() {
|
// Expected at least one database
|
||||||
return this.databases.shareDB || this.databases.activeDB;
|
get active(): TAppDatabase {
|
||||||
|
return this.databases.shareDB || this.databases.activeDB!;
|
||||||
}
|
}
|
||||||
|
|
||||||
get share() {
|
get share() {
|
||||||
|
@ -116,11 +124,11 @@ class DB {
|
||||||
Setting,
|
Setting,
|
||||||
User
|
User
|
||||||
]
|
]
|
||||||
});
|
}) as TAppDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
setActiveDB(database) {
|
setActiveDB(database: string) {
|
||||||
this.databases.activeDB = getDatabase(database);
|
this.databases.activeDB = getDatabase(database) as TAppDatabase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { Database, Collection } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
|
import * as models from './model';
|
||||||
|
import * as definitions from '../../definitions';
|
||||||
|
|
||||||
|
export type TAppDatabaseNames =
|
||||||
|
| typeof models.SUBSCRIPTIONS_TABLE
|
||||||
|
| typeof models.ROOMS_TABLE
|
||||||
|
| typeof models.MESSAGES_TABLE
|
||||||
|
| typeof models.THREADS_TABLE
|
||||||
|
| typeof models.THREAD_MESSAGES_TABLE
|
||||||
|
| typeof models.CUSTOM_EMOJIS_TABLE
|
||||||
|
| typeof models.FREQUENTLY_USED_EMOJIS_TABLE
|
||||||
|
| typeof models.UPLOADS_TABLE
|
||||||
|
| typeof models.SETTINGS_TABLE
|
||||||
|
| typeof models.ROLES_TABLE
|
||||||
|
| typeof models.PERMISSIONS_TABLE
|
||||||
|
| typeof models.SLASH_COMMANDS_TABLE
|
||||||
|
| typeof models.USERS_TABLE;
|
||||||
|
|
||||||
|
// Verify if T extends one type from TAppDatabaseNames, and if is truly,
|
||||||
|
// returns the specific model type.
|
||||||
|
// https://stackoverflow.com/a/54166010 TypeScript function return type based on input parameter
|
||||||
|
type ObjectType<T> = T extends typeof models.SUBSCRIPTIONS_TABLE
|
||||||
|
? definitions.TSubscriptionModel
|
||||||
|
: T extends typeof models.ROOMS_TABLE
|
||||||
|
? definitions.TRoomModel
|
||||||
|
: T extends typeof models.MESSAGES_TABLE
|
||||||
|
? definitions.TMessageModel
|
||||||
|
: T extends typeof models.THREADS_TABLE
|
||||||
|
? definitions.TThreadModel
|
||||||
|
: T extends typeof models.THREAD_MESSAGES_TABLE
|
||||||
|
? definitions.TThreadMessageModel
|
||||||
|
: T extends typeof models.CUSTOM_EMOJIS_TABLE
|
||||||
|
? definitions.TCustomEmojiModel
|
||||||
|
: T extends typeof models.FREQUENTLY_USED_EMOJIS_TABLE
|
||||||
|
? definitions.TFrequentlyUsedEmojiModel
|
||||||
|
: T extends typeof models.UPLOADS_TABLE
|
||||||
|
? definitions.TUploadModel
|
||||||
|
: T extends typeof models.SETTINGS_TABLE
|
||||||
|
? definitions.TSettingsModel
|
||||||
|
: T extends typeof models.ROLES_TABLE
|
||||||
|
? definitions.TRoleModel
|
||||||
|
: T extends typeof models.PERMISSIONS_TABLE
|
||||||
|
? definitions.TPermissionModel
|
||||||
|
: T extends typeof models.SLASH_COMMANDS_TABLE
|
||||||
|
? definitions.TSlashCommandModel
|
||||||
|
: T extends typeof models.USERS_TABLE
|
||||||
|
? definitions.TUserModel
|
||||||
|
: never;
|
||||||
|
|
||||||
|
export type TAppDatabase = {
|
||||||
|
get: <T extends TAppDatabaseNames>(db: T) => Collection<ObjectType<T>>;
|
||||||
|
} & Database;
|
||||||
|
|
||||||
|
// Migration to server database
|
||||||
|
export type TServerDatabaseNames =
|
||||||
|
| typeof models.SERVERS_TABLE
|
||||||
|
| typeof models.LOGGED_USERS_TABLE
|
||||||
|
| typeof models.SERVERS_HISTORY_TABLE;
|
||||||
|
|
||||||
|
type ObjectServerType<T> = T extends typeof models.SERVERS_TABLE
|
||||||
|
? definitions.TServerModel
|
||||||
|
: T extends typeof models.LOGGED_USERS_TABLE
|
||||||
|
? definitions.TLoggedUserModel
|
||||||
|
: T extends typeof models.SERVERS_HISTORY_TABLE
|
||||||
|
? definitions.TServerHistoryModel
|
||||||
|
: never;
|
||||||
|
|
||||||
|
export type TServerDatabase = {
|
||||||
|
get: <T extends TServerDatabaseNames>(db: T) => Collection<ObjectServerType<T>>;
|
||||||
|
} & Database;
|
|
@ -3,8 +3,10 @@ import { date, field, json } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
|
export const CUSTOM_EMOJIS_TABLE = 'custom_emojis';
|
||||||
|
|
||||||
export default class CustomEmoji extends Model {
|
export default class CustomEmoji extends Model {
|
||||||
static table = 'custom_emojis';
|
static table = CUSTOM_EMOJIS_TABLE;
|
||||||
|
|
||||||
@field('name') name;
|
@field('name') name;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { Model } from '@nozbe/watermelondb';
|
import { Model } from '@nozbe/watermelondb';
|
||||||
import { field } from '@nozbe/watermelondb/decorators';
|
import { field } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
|
export const FREQUENTLY_USED_EMOJIS_TABLE = 'frequently_used_emojis';
|
||||||
export default class FrequentlyUsedEmoji extends Model {
|
export default class FrequentlyUsedEmoji extends Model {
|
||||||
static table = 'frequently_used_emojis';
|
static table = FREQUENTLY_USED_EMOJIS_TABLE;
|
||||||
|
|
||||||
@field('content') content;
|
@field('content') content;
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ import { date, field, json, relation } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
export const TABLE_NAME = 'messages';
|
export const MESSAGES_TABLE = 'messages';
|
||||||
|
|
||||||
export default class Message extends Model {
|
export default class Message extends Model {
|
||||||
static table = TABLE_NAME;
|
static table = MESSAGES_TABLE;
|
||||||
|
|
||||||
static associations = {
|
static associations = {
|
||||||
subscriptions: { type: 'belongs_to', key: 'rid' }
|
subscriptions: { type: 'belongs_to', key: 'rid' }
|
||||||
|
|
|
@ -3,8 +3,10 @@ import { date, json } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
|
export const PERMISSIONS_TABLE = 'permissions';
|
||||||
|
|
||||||
export default class Permission extends Model {
|
export default class Permission extends Model {
|
||||||
static table = 'permissions';
|
static table = PERMISSIONS_TABLE;
|
||||||
|
|
||||||
@json('roles', sanitizer) roles;
|
@json('roles', sanitizer) roles;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { Model } from '@nozbe/watermelondb';
|
import { Model } from '@nozbe/watermelondb';
|
||||||
import { field } from '@nozbe/watermelondb/decorators';
|
import { field } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
|
export const ROLES_TABLE = 'roles';
|
||||||
|
|
||||||
export default class Role extends Model {
|
export default class Role extends Model {
|
||||||
static table = 'roles';
|
static table = ROLES_TABLE;
|
||||||
|
|
||||||
@field('description') description;
|
@field('description') description;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,10 @@ import { field, json } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
|
export const ROOMS_TABLE = 'rooms';
|
||||||
|
|
||||||
export default class Room extends Model {
|
export default class Room extends Model {
|
||||||
static table = 'rooms';
|
static table = ROOMS_TABLE;
|
||||||
|
|
||||||
@json('custom_fields', sanitizer) customFields;
|
@json('custom_fields', sanitizer) customFields;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { Model } from '@nozbe/watermelondb';
|
import { Model } from '@nozbe/watermelondb';
|
||||||
import { date, field, readonly } from '@nozbe/watermelondb/decorators';
|
import { date, field, readonly } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
|
export const SERVERS_HISTORY_TABLE = 'servers_history';
|
||||||
|
|
||||||
export default class ServersHistory extends Model {
|
export default class ServersHistory extends Model {
|
||||||
static table = 'servers_history';
|
static table = SERVERS_HISTORY_TABLE;
|
||||||
|
|
||||||
@field('url') url;
|
@field('url') url;
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,10 @@ import { date, field, json } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
|
export const SETTINGS_TABLE = 'settings';
|
||||||
|
|
||||||
export default class Setting extends Model {
|
export default class Setting extends Model {
|
||||||
static table = 'settings';
|
static table = SETTINGS_TABLE;
|
||||||
|
|
||||||
@field('value_as_string') valueAsString;
|
@field('value_as_string') valueAsString;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { Model } from '@nozbe/watermelondb';
|
import { Model } from '@nozbe/watermelondb';
|
||||||
import { field } from '@nozbe/watermelondb/decorators';
|
import { field } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
|
export const SLASH_COMMANDS_TABLE = 'slash_commands';
|
||||||
|
|
||||||
export default class SlashCommand extends Model {
|
export default class SlashCommand extends Model {
|
||||||
static table = 'slash_commands';
|
static table = SLASH_COMMANDS_TABLE;
|
||||||
|
|
||||||
@field('params') params;
|
@field('params') params;
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ import { children, date, field, json } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
export const TABLE_NAME = 'subscriptions';
|
export const SUBSCRIPTIONS_TABLE = 'subscriptions';
|
||||||
|
|
||||||
export default class Subscription extends Model {
|
export default class Subscription extends Model {
|
||||||
static table = TABLE_NAME;
|
static table = SUBSCRIPTIONS_TABLE;
|
||||||
|
|
||||||
static associations = {
|
static associations = {
|
||||||
messages: { type: 'has_many', foreignKey: 'rid' },
|
messages: { type: 'has_many', foreignKey: 'rid' },
|
||||||
|
|
|
@ -3,10 +3,10 @@ import { date, field, json, relation } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
export const TABLE_NAME = 'threads';
|
export const THREADS_TABLE = 'threads';
|
||||||
|
|
||||||
export default class Thread extends Model {
|
export default class Thread extends Model {
|
||||||
static table = TABLE_NAME;
|
static table = THREADS_TABLE;
|
||||||
|
|
||||||
static associations = {
|
static associations = {
|
||||||
subscriptions: { type: 'belongs_to', key: 'rid' }
|
subscriptions: { type: 'belongs_to', key: 'rid' }
|
||||||
|
|
|
@ -3,10 +3,10 @@ import { date, field, json, relation } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
export const TABLE_NAME = 'thread_messages';
|
export const THREAD_MESSAGES_TABLE = 'thread_messages';
|
||||||
|
|
||||||
export default class ThreadMessage extends Model {
|
export default class ThreadMessage extends Model {
|
||||||
static table = TABLE_NAME;
|
static table = THREAD_MESSAGES_TABLE;
|
||||||
|
|
||||||
static associations = {
|
static associations = {
|
||||||
subscriptions: { type: 'belongs_to', key: 'subscription_id' }
|
subscriptions: { type: 'belongs_to', key: 'subscription_id' }
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { Model } from '@nozbe/watermelondb';
|
import { Model } from '@nozbe/watermelondb';
|
||||||
import { field, relation } from '@nozbe/watermelondb/decorators';
|
import { field, relation } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
|
export const UPLOADS_TABLE = 'uploads';
|
||||||
|
|
||||||
export default class Upload extends Model {
|
export default class Upload extends Model {
|
||||||
static table = 'uploads';
|
static table = UPLOADS_TABLE;
|
||||||
|
|
||||||
static associations = {
|
static associations = {
|
||||||
subscriptions: { type: 'belongs_to', key: 'rid' }
|
subscriptions: { type: 'belongs_to', key: 'rid' }
|
||||||
|
|
|
@ -3,8 +3,10 @@ import { field, json } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../utils';
|
import { sanitizer } from '../utils';
|
||||||
|
|
||||||
|
export const USERS_TABLE = 'users';
|
||||||
|
|
||||||
export default class User extends Model {
|
export default class User extends Model {
|
||||||
static table = 'users';
|
static table = USERS_TABLE;
|
||||||
|
|
||||||
@field('_id') _id;
|
@field('_id') _id;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
export * from './CustomEmoji';
|
||||||
|
export * from './FrequentlyUsedEmoji';
|
||||||
|
export * from './Message';
|
||||||
|
export * from './Permission';
|
||||||
|
export * from './Role';
|
||||||
|
export * from './Room';
|
||||||
|
export * from './Setting';
|
||||||
|
export * from './SlashCommand';
|
||||||
|
export * from './Subscription';
|
||||||
|
export * from './Thread';
|
||||||
|
export * from './ThreadMessage';
|
||||||
|
export * from './Upload';
|
||||||
|
export * from './User';
|
||||||
|
export * from './ServersHistory';
|
||||||
|
export * from './servers/Server';
|
||||||
|
export * from './servers/User';
|
|
@ -1,8 +1,10 @@
|
||||||
import { Model } from '@nozbe/watermelondb';
|
import { Model } from '@nozbe/watermelondb';
|
||||||
import { date, field } from '@nozbe/watermelondb/decorators';
|
import { date, field } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
|
export const SERVERS_TABLE = 'servers';
|
||||||
|
|
||||||
export default class Server extends Model {
|
export default class Server extends Model {
|
||||||
static table = 'servers';
|
static table = SERVERS_TABLE;
|
||||||
|
|
||||||
@field('name') name;
|
@field('name') name;
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,10 @@ import { field, json } from '@nozbe/watermelondb/decorators';
|
||||||
|
|
||||||
import { sanitizer } from '../../utils';
|
import { sanitizer } from '../../utils';
|
||||||
|
|
||||||
|
export const LOGGED_USERS_TABLE = 'users';
|
||||||
|
|
||||||
export default class User extends Model {
|
export default class User extends Model {
|
||||||
static table = 'users';
|
static table = LOGGED_USERS_TABLE;
|
||||||
|
|
||||||
@field('token') token;
|
@field('token') token;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import database from '..';
|
import database from '..';
|
||||||
import { TABLE_NAME } from '../model/Message';
|
import { MESSAGES_TABLE } from '../model/Message';
|
||||||
|
|
||||||
const getCollection = db => db.get(TABLE_NAME);
|
const getCollection = db => db.get(MESSAGES_TABLE);
|
||||||
|
|
||||||
export const getMessageById = async messageId => {
|
export const getMessageById = async messageId => {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import database from '..';
|
import database from '..';
|
||||||
import { TABLE_NAME } from '../model/Subscription';
|
import { SUBSCRIPTIONS_TABLE } from '../model/Subscription';
|
||||||
|
|
||||||
const getCollection = db => db.get(TABLE_NAME);
|
const getCollection = db => db.get(SUBSCRIPTIONS_TABLE);
|
||||||
|
|
||||||
export const getSubscriptionByRoomId = async rid => {
|
export const getSubscriptionByRoomId = async rid => {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import database from '..';
|
import database from '..';
|
||||||
import { TABLE_NAME } from '../model/Thread';
|
import { THREADS_TABLE } from '../model/Thread';
|
||||||
|
|
||||||
const getCollection = db => db.get(TABLE_NAME);
|
const getCollection = db => db.get(THREADS_TABLE);
|
||||||
|
|
||||||
export const getThreadById = async tmid => {
|
export const getThreadById = async tmid => {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import database from '..';
|
import database from '..';
|
||||||
import { TABLE_NAME } from '../model/ThreadMessage';
|
import { THREAD_MESSAGES_TABLE } from '../model/ThreadMessage';
|
||||||
|
|
||||||
const getCollection = db => db.get(TABLE_NAME);
|
const getCollection = db => db.get(THREAD_MESSAGES_TABLE);
|
||||||
|
|
||||||
export const getThreadMessageById = async messageId => {
|
export const getThreadMessageById = async messageId => {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
|
|
|
@ -61,7 +61,7 @@ const PERMISSIONS = [
|
||||||
|
|
||||||
export async function setPermissions() {
|
export async function setPermissions() {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const permissionsCollection = db.collections.get('permissions');
|
const permissionsCollection = db.get('permissions');
|
||||||
const allPermissions = await permissionsCollection.query(Q.where('id', Q.oneOf(PERMISSIONS))).fetch();
|
const allPermissions = await permissionsCollection.query(Q.where('id', Q.oneOf(PERMISSIONS))).fetch();
|
||||||
const parsed = allPermissions.reduce((acc, item) => ({ ...acc, [item.id]: item.roles }), {});
|
const parsed = allPermissions.reduce((acc, item) => ({ ...acc, [item.id]: item.roles }), {});
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import protectedFunction from './helpers/protectedFunction';
|
||||||
|
|
||||||
export async function setRoles() {
|
export async function setRoles() {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const rolesCollection = db.collections.get('roles');
|
const rolesCollection = db.get('roles');
|
||||||
const allRoles = await rolesCollection.query().fetch();
|
const allRoles = await rolesCollection.query().fetch();
|
||||||
const parsed = allRoles.reduce((acc, item) => ({ ...acc, [item.id]: item.description || item.id }), {});
|
const parsed = allRoles.reduce((acc, item) => ({ ...acc, [item.id]: item.description || item.id }), {});
|
||||||
reduxStore.dispatch(setRolesAction(parsed));
|
reduxStore.dispatch(setRolesAction(parsed));
|
||||||
|
|
|
@ -811,6 +811,16 @@ const RocketChat = {
|
||||||
encrypted
|
encrypted
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getDiscussions({ roomId, offset, count, text }) {
|
||||||
|
const params = {
|
||||||
|
roomId,
|
||||||
|
offset,
|
||||||
|
count,
|
||||||
|
...(text && { text })
|
||||||
|
};
|
||||||
|
// RC 2.4.0
|
||||||
|
return this.sdk.get('chat.getDiscussions', params);
|
||||||
|
},
|
||||||
createTeam({ name, users, type, readOnly, broadcast, encrypted }) {
|
createTeam({ name, users, type, readOnly, broadcast, encrypted }) {
|
||||||
const params = {
|
const params = {
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { SET_ACTIVE_USERS } from '../actions/actionsTypes';
|
||||||
type TUserStatus = 'online' | 'offline';
|
type TUserStatus = 'online' | 'offline';
|
||||||
export interface IActiveUser {
|
export interface IActiveUser {
|
||||||
status: TUserStatus;
|
status: TUserStatus;
|
||||||
statusText?: string;
|
statusText: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IActiveUsers {
|
export interface IActiveUsers {
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import { appStart, appInit, setMasterDetail } from '../actions/app';
|
||||||
|
import { initialState } from './app';
|
||||||
|
import { mockedStore } from './mockedStore';
|
||||||
|
import { RootEnum } from '../definitions';
|
||||||
|
import { APP_STATE } from '../actions/actionsTypes';
|
||||||
|
|
||||||
|
describe('test reducer', () => {
|
||||||
|
it('should return initial state', () => {
|
||||||
|
const state = mockedStore.getState().app;
|
||||||
|
expect(state).toEqual(initialState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return root state after dispatch appStart action', () => {
|
||||||
|
mockedStore.dispatch(appStart({ root: RootEnum.ROOT_INSIDE }));
|
||||||
|
const { root } = mockedStore.getState().app;
|
||||||
|
expect(root).toEqual(RootEnum.ROOT_INSIDE);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return ready state after dispatch appInit action', () => {
|
||||||
|
mockedStore.dispatch(appInit());
|
||||||
|
const { ready } = mockedStore.getState().app;
|
||||||
|
expect(ready).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return ready state after dispatch setMasterDetail action', () => {
|
||||||
|
mockedStore.dispatch(setMasterDetail(false));
|
||||||
|
const { isMasterDetail } = mockedStore.getState().app;
|
||||||
|
expect(isMasterDetail).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct state after app go to foreground', () => {
|
||||||
|
mockedStore.dispatch({ type: APP_STATE.FOREGROUND });
|
||||||
|
const { foreground, background } = mockedStore.getState().app;
|
||||||
|
expect(foreground).toEqual(true);
|
||||||
|
expect(background).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct state after app go to background', () => {
|
||||||
|
mockedStore.dispatch({ type: APP_STATE.BACKGROUND });
|
||||||
|
const { foreground, background } = mockedStore.getState().app;
|
||||||
|
expect(foreground).toEqual(false);
|
||||||
|
expect(background).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,15 +1,26 @@
|
||||||
|
import { TActionApp } from '../actions/app';
|
||||||
|
import { RootEnum } from '../definitions';
|
||||||
import { APP, APP_STATE } from '../actions/actionsTypes';
|
import { APP, APP_STATE } from '../actions/actionsTypes';
|
||||||
|
|
||||||
const initialState = {
|
export interface IApp {
|
||||||
root: null,
|
root?: RootEnum;
|
||||||
|
isMasterDetail: boolean;
|
||||||
|
text?: string;
|
||||||
|
ready: boolean;
|
||||||
|
foreground: boolean;
|
||||||
|
background: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialState: IApp = {
|
||||||
|
root: undefined,
|
||||||
isMasterDetail: false,
|
isMasterDetail: false,
|
||||||
text: null,
|
text: undefined,
|
||||||
ready: false,
|
ready: false,
|
||||||
foreground: true,
|
foreground: true,
|
||||||
background: false
|
background: false
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function app(state = initialState, action) {
|
export default function app(state = initialState, action: TActionApp): IApp {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case APP_STATE.FOREGROUND:
|
case APP_STATE.FOREGROUND:
|
||||||
return {
|
return {
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { connectRequest, connectSuccess, disconnect } from '../actions/connect';
|
||||||
|
import { initialState } from './connect';
|
||||||
|
import { mockedStore } from './mockedStore';
|
||||||
|
|
||||||
|
describe('test reducer', () => {
|
||||||
|
it('should return initial state', () => {
|
||||||
|
const { meteor } = mockedStore.getState();
|
||||||
|
expect(meteor).toEqual(initialState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct meteor state after dispatch connectRequest action', () => {
|
||||||
|
mockedStore.dispatch(connectRequest());
|
||||||
|
const { meteor } = mockedStore.getState();
|
||||||
|
expect(meteor).toEqual({ connecting: true, connected: false });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct meteor state after dispatch connectSuccess action', () => {
|
||||||
|
mockedStore.dispatch(connectSuccess());
|
||||||
|
const { meteor } = mockedStore.getState();
|
||||||
|
expect(meteor).toEqual({ connecting: false, connected: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct meteor state after dispatch disconnect action', () => {
|
||||||
|
mockedStore.dispatch(disconnect());
|
||||||
|
const { meteor } = mockedStore.getState();
|
||||||
|
expect(meteor).toEqual(initialState);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,11 +1,18 @@
|
||||||
|
import { Action } from 'redux';
|
||||||
|
|
||||||
import { METEOR } from '../actions/actionsTypes';
|
import { METEOR } from '../actions/actionsTypes';
|
||||||
|
|
||||||
const initialState = {
|
export interface IConnect {
|
||||||
|
connecting: boolean;
|
||||||
|
connected: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialState: IConnect = {
|
||||||
connecting: false,
|
connecting: false,
|
||||||
connected: false
|
connected: false
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function connect(state = initialState, action) {
|
export default function connect(state = initialState, action: Action): IConnect {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case METEOR.REQUEST:
|
case METEOR.REQUEST:
|
||||||
return {
|
return {
|
|
@ -1,36 +0,0 @@
|
||||||
import { CREATE_CHANNEL } from '../actions/actionsTypes';
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
isFetching: false,
|
|
||||||
failure: false,
|
|
||||||
result: {},
|
|
||||||
error: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function (state = initialState, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case CREATE_CHANNEL.REQUEST:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isFetching: true,
|
|
||||||
failure: false,
|
|
||||||
error: {}
|
|
||||||
};
|
|
||||||
case CREATE_CHANNEL.SUCCESS:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isFetching: false,
|
|
||||||
failure: false,
|
|
||||||
result: action.data
|
|
||||||
};
|
|
||||||
case CREATE_CHANNEL.FAILURE:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
isFetching: false,
|
|
||||||
failure: true,
|
|
||||||
error: action.err
|
|
||||||
};
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue