Skip to content

Commit

Permalink
Timeline: repair oldest/newest metrics if we fetch nothing
Browse files Browse the repository at this point in the history
  • Loading branch information
scottnonnenberg-signal committed Dec 4, 2020
1 parent 56ae4a4 commit 6832b8a
Show file tree
Hide file tree
Showing 47 changed files with 579 additions and 173 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Expand Up @@ -150,7 +150,7 @@ module.exports = {
rules,
},
{
files: ['**/*.stories.tsx', 'ts/build/**', 'ts/test/**'],
files: ['**/*.stories.tsx', 'ts/build/**', 'ts/test-*/**'],
rules: {
...rules,
'import/no-extraneous-dependencies': 'off',
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -29,8 +29,8 @@
"publish-to-apt": "NAME=$npm_package_name VERSION=$npm_package_version ./aptly.sh",
"test": "yarn test-node && yarn test-electron",
"test-electron": "yarn grunt test",
"test-node": "electron-mocha --recursive test/app test/modules ts/test",
"test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test",
"test-node": "electron-mocha --recursive test/app test/modules ts/test-node ts/test-both",
"test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test-node ts/test-both",
"eslint": "eslint .",
"lint": "yarn format --list-different && yarn eslint",
"lint-deps": "node ts/util/lint/linter.js",
Expand Down
7 changes: 5 additions & 2 deletions preload.js
Expand Up @@ -563,9 +563,12 @@ try {
};

/* eslint-disable global-require, import/no-extraneous-dependencies */
require('./ts/test-electron/models/messages_test');
require('./ts/test-both/state/ducks/conversations_test');
require('./ts/test-both/state/selectors/conversations_test');
require('./ts/test-both/state/selectors/items_test');

require('./ts/test-electron/linkPreviews/linkPreviewFetch_test');
require('./ts/test-electron/state/ducks/conversations_test');
require('./ts/test-electron/models/messages_test');
require('./ts/test-electron/state/ducks/calling_test');
require('./ts/test-electron/state/selectors/calling_test');

Expand Down
103 changes: 103 additions & 0 deletions ts/state/ducks/conversations.ts
Expand Up @@ -13,6 +13,8 @@ import {
values,
without,
} from 'lodash';

import { getOwn } from '../../util/getOwn';
import { trigger } from '../../shims/events';
import { NoopActionType } from './noop';
import { AttachmentType } from '../../types/Attachment';
Expand Down Expand Up @@ -281,6 +283,19 @@ export type MessagesAddedActionType = {
isActive: boolean;
};
};

export type RepairNewestMessageActionType = {
type: 'REPAIR_NEWEST_MESSAGE';
payload: {
conversationId: string;
};
};
export type RepairOldestMessageActionType = {
type: 'REPAIR_OLDEST_MESSAGE';
payload: {
conversationId: string;
};
};
export type MessagesResetActionType = {
type: 'MESSAGES_RESET';
payload: {
Expand Down Expand Up @@ -367,6 +382,8 @@ export type ConversationActionType =
| MessageChangedActionType
| MessageDeletedActionType
| MessagesAddedActionType
| RepairNewestMessageActionType
| RepairOldestMessageActionType
| MessagesResetActionType
| SetMessagesLoadingActionType
| SetIsNearBottomActionType
Expand Down Expand Up @@ -407,6 +424,8 @@ export const actions = {
openConversationExternal,
showInbox,
showArchivedConversations,
repairNewestMessage,
repairOldestMessage,
};

function conversationAdded(
Expand Down Expand Up @@ -511,6 +530,28 @@ function messagesAdded(
},
};
}

function repairNewestMessage(
conversationId: string
): RepairNewestMessageActionType {
return {
type: 'REPAIR_NEWEST_MESSAGE',
payload: {
conversationId,
},
};
}
function repairOldestMessage(
conversationId: string
): RepairOldestMessageActionType {
return {
type: 'REPAIR_OLDEST_MESSAGE',
payload: {
conversationId,
},
};
}

function messagesReset(
conversationId: string,
messages: Array<MessageType>,
Expand Down Expand Up @@ -1119,6 +1160,68 @@ export function reducer(
},
};
}

if (action.type === 'REPAIR_NEWEST_MESSAGE') {
const { conversationId } = action.payload;
const { messagesByConversation, messagesLookup } = state;

const existingConversation = getOwn(messagesByConversation, conversationId);
if (!existingConversation) {
return state;
}

const { messageIds } = existingConversation;
const lastId =
messageIds && messageIds.length
? messageIds[messageIds.length - 1]
: undefined;
const last = lastId ? getOwn(messagesLookup, lastId) : undefined;
const newest = last ? pick(last, ['id', 'received_at']) : undefined;

return {
...state,
messagesByConversation: {
...messagesByConversation,
[conversationId]: {
...existingConversation,
metrics: {
...existingConversation.metrics,
newest,
},
},
},
};
}

if (action.type === 'REPAIR_OLDEST_MESSAGE') {
const { conversationId } = action.payload;
const { messagesByConversation, messagesLookup } = state;

const existingConversation = getOwn(messagesByConversation, conversationId);
if (!existingConversation) {
return state;
}

const { messageIds } = existingConversation;
const firstId = messageIds && messageIds.length ? messageIds[0] : undefined;
const first = firstId ? getOwn(messagesLookup, firstId) : undefined;
const oldest = first ? pick(first, ['id', 'received_at']) : undefined;

return {
...state,
messagesByConversation: {
...messagesByConversation,
[conversationId]: {
...existingConversation,
metrics: {
...existingConversation.metrics,
oldest,
},
},
},
};
}

if (action.type === 'MESSAGES_ADDED') {
const { conversationId, isActive, isNewMessage, messages } = action.payload;
const { messagesByConversation, messagesLookup } = state;
Expand Down
13 changes: 7 additions & 6 deletions ts/state/selectors/conversations.ts
Expand Up @@ -15,6 +15,7 @@ import {
MessagesByConversationType,
MessageType,
} from '../ducks/conversations';

import { getBubbleProps } from '../../shims/Whisper';
import { PropsDataType as TimelinePropsType } from '../../components/conversation/Timeline';
import { TimelineItemType } from '../../components/conversation/TimelineItem';
Expand All @@ -26,6 +27,7 @@ import {
getUserConversationId,
getUserNumber,
} from './user';
import { getPinnedConversationIds } from './items';

export const getConversations = (state: StateType): ConversationsStateType =>
state.conversations;
Expand Down Expand Up @@ -127,7 +129,8 @@ export const getConversationComparator = createSelector(
export const _getLeftPaneLists = (
lookup: ConversationLookupType,
comparator: (left: ConversationType, right: ConversationType) => number,
selectedConversation?: string
selectedConversation?: string,
pinnedConversationIds?: Array<string>
): {
conversations: Array<ConversationType>;
archivedConversations: Array<ConversationType>;
Expand Down Expand Up @@ -162,13 +165,10 @@ export const _getLeftPaneLists = (
conversations.sort(comparator);
archivedConversations.sort(comparator);

const pinnedConversationIds = window.storage.get<Array<string>>(
'pinnedConversationIds',
[]
);
pinnedConversations.sort(
(a, b) =>
pinnedConversationIds.indexOf(a.id) - pinnedConversationIds.indexOf(b.id)
(pinnedConversationIds || []).indexOf(a.id) -
(pinnedConversationIds || []).indexOf(b.id)
);

return { conversations, archivedConversations, pinnedConversations };
Expand All @@ -178,6 +178,7 @@ export const getLeftPaneLists = createSelector(
getConversationLookup,
getConversationComparator,
getSelectedConversation,
getPinnedConversationIds,
_getLeftPaneLists
);

Expand Down
20 changes: 20 additions & 0 deletions ts/state/selectors/items.ts
@@ -0,0 +1,20 @@
// Copyright 2019-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only

import { createSelector } from 'reselect';

import { StateType } from '../reducer';
import { ItemsStateType } from '../ducks/items';

export const getItems = (state: StateType): ItemsStateType => state.items;

export const getUserAgent = createSelector(
getItems,
(state: ItemsStateType): string => state.userAgent as string
);

export const getPinnedConversationIds = createSelector(
getItems,
(state: ItemsStateType): Array<string> =>
(state.pinnedConversationIds || []) as Array<string>
);
3 changes: 2 additions & 1 deletion ts/state/selectors/search.ts
Expand Up @@ -24,7 +24,8 @@ import {
} from '../../components/SearchResults';
import { PropsDataType as MessageSearchResultPropsDataType } from '../../components/MessageSearchResult';

import { getRegionCode, getUserAgent, getUserNumber } from './user';
import { getRegionCode, getUserNumber } from './user';
import { getUserAgent } from './items';
import {
GetConversationByIdType,
getConversationLookup,
Expand Down
8 changes: 0 additions & 8 deletions ts/state/selectors/user.ts
Expand Up @@ -7,12 +7,9 @@ import { LocalizerType } from '../../types/Util';

import { StateType } from '../reducer';
import { UserStateType } from '../ducks/user';
import { ItemsStateType } from '../ducks/items';

export const getUser = (state: StateType): UserStateType => state.user;

export const getItems = (state: StateType): ItemsStateType => state.items;

export const getUserNumber = createSelector(
getUser,
(state: UserStateType): string => state.ourNumber
Expand All @@ -33,11 +30,6 @@ export const getUserUuid = createSelector(
(state: UserStateType): string => state.ourUuid
);

export const getUserAgent = createSelector(
getItems,
(state: ItemsStateType): string => state.userAgent as string
);

export const getIntl = createSelector(
getUser,
(state: UserStateType): LocalizerType => state.i18n
Expand Down

0 comments on commit 6832b8a

Please sign in to comment.