Skip to content

Commit

Permalink
New Idle timer; messages not marked read if user is idle
Browse files Browse the repository at this point in the history
  • Loading branch information
scottnonnenberg-signal committed Sep 24, 2019
1 parent b77246a commit 8ccb893
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 55 deletions.
1 change: 0 additions & 1 deletion background.html
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ <h3>{{ message }}</h3>
<script type='text/javascript' src='js/signal_protocol_store.js'></script>
<script type='text/javascript' src='js/libtextsecure.js'></script>

<script type='text/javascript' src='js/focus_listener.js'></script>
<script type='text/javascript' src='js/notifications.js'></script>
<script type='text/javascript' src='js/delivery_receipts.js'></script>
<script type='text/javascript' src='js/read_receipts.js'></script>
Expand Down
39 changes: 38 additions & 1 deletion js/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,43 @@
false
);

// Idle timer - you're active for ACTIVE_TIMEOUT after one of these events
const ACTIVE_TIMEOUT = 15 * 1000;
const ACTIVE_EVENTS = [
'click',
'keypress',
'mousedown',
'mousemove',
// 'scroll', // this is triggered by Timeline re-renders, can't use
'touchstart',
'wheel',
];

const LISTENER_DEBOUNCE = 5 * 1000;
let activeHandlers = [];
let activeTimestamp = Date.now();

window.resetActiveTimer = _.throttle(() => {
const previouslyActive = window.isActive();
activeTimestamp = Date.now();
if (!previouslyActive) {
activeHandlers.forEach(handler => handler());
}
}, LISTENER_DEBOUNCE);

ACTIVE_EVENTS.forEach(name => {
document.addEventListener(name, window.resetActiveTimer, true);
});

window.isActive = () => {
const now = Date.now();
return now <= activeTimestamp + ACTIVE_TIMEOUT;
};
window.registerForActive = handler => activeHandlers.push(handler);
window.unregisterForActive = handler => {
activeHandlers = activeHandlers.filter(item => item !== handler);
};

// Load these images now to ensure that they don't flicker on first use
window.Signal.EmojiLib.preloadImages();
const images = [];
Expand Down Expand Up @@ -712,7 +749,7 @@
}
});

window.addEventListener('focus', () => Whisper.Notifications.clear());
window.registerForActive(() => Whisper.Notifications.clear());
window.addEventListener('unload', () => Whisper.Notifications.fastClear());

Whisper.events.on('showConversation', (id, messageId) => {
Expand Down
14 changes: 0 additions & 14 deletions js/focus_listener.js

This file was deleted.

2 changes: 1 addition & 1 deletion js/models/conversations.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@
this.id,
[model.getReduxData()],
isNewMessage,
document.hasFocus()
window.isActive()
);
}

Expand Down
3 changes: 1 addition & 2 deletions js/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

/* global drawAttention: false */
/* global i18n: false */
/* global isFocused: false */
/* global Signal: false */
/* global storage: false */
/* global Whisper: false */
Expand Down Expand Up @@ -54,7 +53,7 @@
}

const { isEnabled } = this;
const isAppFocused = isFocused();
const isAppFocused = window.isActive();
const isAudioNotificationEnabled =
storage.get('audio-notification') || false;
const isAudioNotificationSupported = Settings.isAudioNotificationSupported();
Expand Down
2 changes: 1 addition & 1 deletion js/views/app_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
if (!$.contains(this.el, this.inboxView.el)) {
this.openView(this.inboxView);
}
window.focus(); // FIXME

return Promise.resolve();
},
onEmpty() {
Expand Down
10 changes: 4 additions & 6 deletions js/views/conversation_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@
id,
models.map(model => model.getReduxData()),
isNewMessage,
document.hasFocus()
window.isActive()
);
} catch (error) {
setMessagesLoading(conversationId, true);
Expand Down Expand Up @@ -493,7 +493,7 @@
id,
models.map(model => model.getReduxData()),
isNewMessage,
document.hasFocus()
window.isActive()
);
} catch (error) {
setMessagesLoading(conversationId, false);
Expand All @@ -502,10 +502,8 @@
finish();
}
};
const markMessageRead = async (messageId, forceFocus) => {
// We need a forceFocus parameter because the BrowserWindow focus event fires
// before the document realizes that it has focus.
if (!document.hasFocus() && !forceFocus) {
const markMessageRead = async messageId => {
if (!window.isActive()) {
return;
}

Expand Down
8 changes: 0 additions & 8 deletions preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ const { remote } = electron;
const { app } = remote;
const { systemPreferences } = remote.require('electron');

const browserWindow = remote.getCurrentWindow();
let focusHandlers = [];
browserWindow.on('focus', () => focusHandlers.forEach(handler => handler()));
window.registerForFocus = handler => focusHandlers.push(handler);
window.unregisterForFocus = handler => {
focusHandlers = focusHandlers.filter(item => item !== handler);
};

// Waiting for clients to implement changes on receive side
window.ENABLE_STICKER_SEND = true;
window.TIMESTAMP_VALIDATION = false;
Expand Down
1 change: 0 additions & 1 deletion test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,6 @@ <h3>{{ message }}</h3>
<script type='text/javascript' src='../js/expiring_messages.js' data-cover></script>
<script type='text/javascript' src='../js/expiring_tap_to_view_messages.js' data-cover></script>
<script type='text/javascript' src='../js/notifications.js' data-cover></script>
<script type='text/javascript' src='../js/focus_listener.js'></script>

<script type="text/javascript" src="../js/chromium.js" data-cover></script>

Expand Down
15 changes: 5 additions & 10 deletions ts/components/conversation/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type PropsActionsType = {
loadOlderMessages: (messageId: string) => unknown;
loadNewerMessages: (messageId: string) => unknown;
loadNewestMessages: (messageId: string) => unknown;
markMessageRead: (messageId: string, forceFocus?: boolean) => unknown;
markMessageRead: (messageId: string) => unknown;
} & MessageActionsType &
SafetyNumberActionsType;

Expand Down Expand Up @@ -402,7 +402,7 @@ export class Timeline extends React.PureComponent<Props, State> {

// tslint:disable-next-line member-ordering cyclomatic-complexity
public updateWithVisibleRows = debounce(
(forceFocus?: boolean) => {
() => {
const {
unreadCount,
haveNewest,
Expand All @@ -426,7 +426,7 @@ export class Timeline extends React.PureComponent<Props, State> {
return;
}

markMessageRead(newest.id, forceFocus);
markMessageRead(newest.id);

const rowCount = this.getRowCount();

Expand Down Expand Up @@ -710,19 +710,14 @@ export class Timeline extends React.PureComponent<Props, State> {
public componentDidMount() {
this.updateWithVisibleRows();
// @ts-ignore
window.registerForFocus(this.forceFocusVisibleRowUpdate);
window.registerForActive(this.updateWithVisibleRows);
}

public componentWillUnmount() {
// @ts-ignore
window.unregisterForFocus(this.forceFocusVisibleRowUpdate);
window.unregisterForActive(this.updateWithVisibleRows);
}

public forceFocusVisibleRowUpdate = () => {
const forceFocus = true;
this.updateWithVisibleRows(forceFocus);
};

// tslint:disable-next-line cyclomatic-complexity max-func-body-length
public componentDidUpdate(prevProps: Props) {
const {
Expand Down
15 changes: 5 additions & 10 deletions ts/state/ducks/conversations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export type MessagesAddedActionType = {
conversationId: string;
messages: Array<MessageType>;
isNewMessage: boolean;
isFocused: boolean;
isActive: boolean;
};
};
export type MessagesResetActionType = {
Expand Down Expand Up @@ -357,15 +357,15 @@ function messagesAdded(
conversationId: string,
messages: Array<MessageType>,
isNewMessage: boolean,
isFocused: boolean
isActive: boolean
): MessagesAddedActionType {
return {
type: 'MESSAGES_ADDED',
payload: {
conversationId,
messages,
isNewMessage,
isFocused,
isActive,
},
};
}
Expand Down Expand Up @@ -870,12 +870,7 @@ export function reducer(
};
}
if (action.type === 'MESSAGES_ADDED') {
const {
conversationId,
isFocused,
isNewMessage,
messages,
} = action.payload;
const { conversationId, isActive, isNewMessage, messages } = action.payload;
const { messagesByConversation, messagesLookup } = state;

const existingConversation = messagesByConversation[conversationId];
Expand Down Expand Up @@ -937,7 +932,7 @@ export function reducer(
const newMessageIds = difference(newIds, existingConversation.messageIds);
const { isNearBottom } = existingConversation;

if ((!isNearBottom || !isFocused) && !oldestUnread) {
if ((!isNearBottom || !isActive) && !oldestUnread) {
const oldestId = newMessageIds.find(messageId => {
const message = lookup[messageId];

Expand Down

0 comments on commit 8ccb893

Please sign in to comment.