Skip to content

Commit

Permalink
Fix archive conversation issues (#732)
Browse files Browse the repository at this point in the history
Co-authored-by: Jarek Radosz <[email protected]>
  • Loading branch information
2 people authored and sindresorhus committed Jan 20, 2019
1 parent 21a6bb1 commit 5c457c7
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 107 deletions.
12 changes: 6 additions & 6 deletions browser.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ html.sidebar-hidden ._1enh {
display: none;
}

/* A utility class for temporarily hiding all dropdown menus */
html.hide-dropdowns .uiContextualLayerPositioner {
visibility: hidden !important;
}

/* Hide footer at login view */
._210n {
display: none;
Expand All @@ -90,14 +95,9 @@ html.sidebar-hidden ._1enh {
border-left: 1px solid rgba(0, 0, 0, 0.1) !important;
}

/* Hide settings menu */
.uiContextualLayerBelowLeft ._5v-0._53il {
display: none !important;
}

/* Hide settings icon */
._30yy._2fug._p {
display: none !important;
visibility: hidden !important;
}

/* Hide title */
Expand Down
221 changes: 120 additions & 101 deletions browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,44 @@ const conversationSelector = '._4u-c._1wfr > ._5f0v.uiScrollableArea';
const selectedConversationSelector = '._5l-3._1ht1._1ht2';
const preferencesSelector = '._10._4ebx.uiLayer._4-hy';

function showSettingsMenu() {
document.querySelector('._30yy._2fug._p').click();
async function withMenu(menuButtonElement, callback) {
const {classList} = document.documentElement;

// Prevent the dropdown menu from displaying
classList.add('hide-dropdowns');

// Click the menu button
menuButtonElement.click();

// Wait for the menu to close before removing the 'hide-dropdowns' class
const menuLayer = document.querySelector('.uiContextualLayerPositioner:not(.hidden_elem)');
const observer = new MutationObserver(() => {
if (menuLayer.classList.contains('hidden_elem')) {
classList.remove('hide-dropdowns');
observer.disconnect();
}
});
observer.observe(menuLayer, {attributes: true, attributeFilter: ['class']});

await callback();
}

async function withSettingsMenu(callback) {
await withMenu(await elementReady('._30yy._2fug._p'), callback);
}

function selectMenuItem(itemNumber) {
const selector = document.querySelector(`._54nq._2i-c._558b._2n_z li:nth-child(${itemNumber}) a`);
const selector = document.querySelector(`.uiLayer:not(.hidden_elem) ._54nq._2i-c._558b._2n_z li:nth-child(${itemNumber}) a`);
selector.click();
}

function selectOtherListViews(itemNumber) {
async function selectOtherListViews(itemNumber) {
// In case one of other views is shown
clickBackButton();

// Create the menu for the below
showSettingsMenu();

selectMenuItem(itemNumber);
await withSettingsMenu(() => {
selectMenuItem(itemNumber);
});
}

function clickBackButton() {
Expand All @@ -49,7 +70,7 @@ ipc.on('new-conversation', () => {
document.querySelector("._30yy[data-href$='/new']").click();
});

ipc.on('log-out', () => {
ipc.on('log-out', async () => {
if (config.get('useWorkChat')) {
// Create the menu for the below
document.querySelector('._5lxs._3qct._p').click();
Expand All @@ -59,9 +80,10 @@ ipc.on('log-out', () => {
nodes[nodes.length - 1].click();
}, 250);
} else {
showSettingsMenu();
const nodes = document.querySelectorAll('._54nq._2i-c._558b._2n_z li:last-child a');
nodes[nodes.length - 1].click();
await withSettingsMenu(() => {
const nodes = document.querySelectorAll('._54nq._2i-c._558b._2n_z li:last-child a');
nodes[nodes.length - 1].click();
});
}
});

Expand Down Expand Up @@ -94,11 +116,18 @@ ipc.on('mute-conversation', () => {
});

ipc.on('delete-conversation', () => {
openDeleteModal();
deleteSelectedConversation();
});

ipc.on('archive-conversation', () => {
openArchiveModal();
ipc.on('archive-conversation', async () => {
const index = selectedConversationIndex();

if (index !== -1) {
archiveSelectedConversation();

const key = index + 1;
await jumpToConversation(key);
}
});

function setSidebarVisibility() {
Expand Down Expand Up @@ -243,53 +272,49 @@ ipc.on('zoom-out', () => {
}
});

ipc.on('jump-to-conversation', (event, index) => {
jumpToConversation(index);
ipc.on('jump-to-conversation', async (event, key) => {
await jumpToConversation(key);
});

function nextConversation() {
const index = getNextIndex(true);
selectConversation(index);
async function nextConversation() {
const index = selectedConversationIndex(1);

if (index !== -1) {
await selectConversation(index);
}
}

function previousConversation() {
const index = getNextIndex(false);
selectConversation(index);
async function previousConversation() {
const index = selectedConversationIndex(-1);

if (index !== -1) {
await selectConversation(index);
}
}

function jumpToConversation(key) {
async function jumpToConversation(key) {
const index = key - 1;
selectConversation(index);
await selectConversation(index);
}

// Focus on the conversation with the given index
function selectConversation(index) {
document.querySelector(listSelector).children[index].firstChild.firstChild.click();
}
async function selectConversation(index) {
const conversationElement = (await elementReady(listSelector)).children[index];

// Returns the index of the selected conversation.
// If no conversation is selected, returns null.
function getIndex() {
const selected = document.querySelector(selectedConversationSelector);
if (!selected) {
return null;
if (conversationElement) {
conversationElement.firstChild.firstChild.click();
}

const list = [...selected.parentNode.children];

return list.indexOf(selected);
}

// Return the index for next node if next is true,
// else returns index for the previous node
function getNextIndex(next) {
function selectedConversationIndex(offset = 0) {
const selected = document.querySelector(selectedConversationSelector);

if (!selected) {
return 0;
return -1;
}

const list = [...selected.parentNode.children];
const index = list.indexOf(selected) + (next ? 1 : -1);
const index = list.indexOf(selected) + offset;

return ((index % list.length) + list.length) % list.length;
}
Expand All @@ -300,48 +325,42 @@ function setZoom(zoomFactor) {
config.set('zoomFactor', zoomFactor);
}

function openConversationMenu() {
const index = getIndex();
if (index === null) {
return false;
}

// Open and close the menu for the below
const menu = document.querySelectorAll('._2j6._5l-3 ._3d85')[index].firstChild;
menu.click();
async function withConversationMenu(callback) {
const menuButton = document.querySelector(`${selectedConversationSelector} ._5blh._4-0h`);

return true;
if (menuButton) {
await withMenu(menuButton, callback);
}
}

function openMuteModal() {
if (!openConversationMenu()) {
return;
}

selectMenuItem(1);
withConversationMenu(() => {
selectMenuItem(1);
});
}

function openArchiveModal() {
if (!openConversationMenu()) {
return;
}
function archiveSelectedConversation() {
const groupConversationProfilePicture = document.querySelector(`${selectedConversationSelector} ._55lu`);
const isGroupConversation = Boolean(groupConversationProfilePicture);

selectMenuItem(3);
withConversationMenu(() => {
selectMenuItem(isGroupConversation ? 4 : 3);
});
}

function openDeleteModal() {
if (!openConversationMenu()) {
return;
}
function deleteSelectedConversation() {
const groupConversationProfilePicture = document.querySelector(`${selectedConversationSelector} ._55lu`);
const isGroupConversation = Boolean(groupConversationProfilePicture);

selectMenuItem(4);
withConversationMenu(() => {
selectMenuItem(isGroupConversation ? 5 : 4);
});
}

async function openPreferences() {
// Create the menu for the below
(await elementReady('._30yy._2fug._p')).click();

selectMenuItem(1);
await withSettingsMenu(() => {
selectMenuItem(1);
});
}

function isPreferencesOpen() {
Expand All @@ -352,33 +371,33 @@ function closePreferences() {
const doneButton = document.querySelector('._3quh._30yy._2t_._5ixy');
doneButton.click();
}

async function sendConversationList() {
const conversations = await Promise.all(
[...document.querySelector(listSelector).children].splice(0, 10).map(async el => {
const profilePic = el.querySelector('._55lt img');
const groupPic = el.querySelector('._4ld- div');

// This is only for group chats
if (groupPic) {
// Slice image source from background-image style property of div
groupPic.src = groupPic.style.backgroundImage.slice(
5,
groupPic.style.backgroundImage.length - 2
);
}

const isConversationMuted = el.classList.contains('_569x');

return {
label: el.querySelector('._1ht6').textContent,
selected: el.classList.contains('_1ht2'),
unread: el.classList.contains('_1ht3') && !isConversationMuted,
icon: await getDataUrlFromImg(
profilePic ? profilePic : groupPic,
el.classList.contains('_1ht3')
)
};
})
[...(await elementReady(listSelector)).children]
.splice(0, 10)
.map(async el => {
const profilePic = el.querySelector('._55lt img');
const groupPic = el.querySelector('._4ld- div');

// This is only for group chats
if (groupPic) {
// Slice image source from background-image style property of div
groupPic.src = groupPic.style.backgroundImage.slice(5, groupPic.style.backgroundImage.length - 2);
}

const isConversationMuted = el.classList.contains('_569x');

return {
label: el.querySelector('._1ht6').textContent,
selected: el.classList.contains('_1ht2'),
unread: el.classList.contains('_1ht3') && !isConversationMuted,
icon: await getDataUrlFromImg(
profilePic ? profilePic : groupPic,
el.classList.contains('_1ht3')
)
};
})
);

ipc.send('conversations', conversations);
Expand Down Expand Up @@ -501,7 +520,7 @@ window.addEventListener('load', () => {

// It's not possible to add multiple accelerators
// so this needs to be done the old-school way
document.addEventListener('keydown', event => {
document.addEventListener('keydown', async event => {
// The `!event.altKey` part is a workaround for https://github.com/electron/electron/issues/13895
const combineKey = is.macos ? event.metaKey : event.ctrlKey && !event.altKey;

Expand All @@ -510,17 +529,17 @@ document.addEventListener('keydown', event => {
}

if (event.key === ']') {
nextConversation();
await nextConversation();
}

if (event.key === '[') {
previousConversation();
await previousConversation();
}

const num = parseInt(event.code.slice(-1), 10);

if (num >= 1 && num <= 9) {
jumpToConversation(num);
await jumpToConversation(num);
}
});

Expand Down

0 comments on commit 5c457c7

Please sign in to comment.