Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix archive conversation issues #732

Merged
merged 19 commits into from
Jan 20, 2019
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
174 changes: 97 additions & 77 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 @@ -236,53 +265,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) {
CvX marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -293,48 +318,42 @@ function setZoom(zoomFactor) {
config.set('zoomFactor', zoomFactor);
}

function openConversationMenu() {
const index = getIndex();
if (index === null) {
return false;
}
async function withConversationMenu(callback) {
const menuButton = document.querySelector(`${selectedConversationSelector} ._5blh._4-0h`);

// Open and close the menu for the below
const menu = document.querySelectorAll('._2j6._5l-3 ._3d85')[index].firstChild;
menu.click();

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 @@ -345,9 +364,10 @@ function closePreferences() {
const doneButton = document.querySelector('._3quh._30yy._2t_._5ixy');
doneButton.click();
}

async function sendConversationList() {
const conversations = await Promise.all(
[...document.querySelector(listSelector).children]
[...(await elementReady(listSelector)).children]
.splice(0, 10)
.map(async el => {
const profilePic = el.querySelector('._55lt img');
Expand Down Expand Up @@ -493,7 +513,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 @@ -502,17 +522,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