Instantly share code, notes, and snippets.
Forked from ctrlMarcio/arc-whatsapp-sidebar.js
Created
February 16, 2023 21:49
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save jpigla/f0e87a0b42a8b8e1d8721df0299f9c0e to your computer and use it in GitHub Desktop.
Boost for Arc Browser (https://arc.net/) based on this tweet: https://twitter.com/adithyashreshti/status/1579896377366044672
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const HALF_OPEN_WIDTH = 80 | |
// this value starts as -1 | |
// and is updated when the sidebar is updated the first time | |
// this is the width to which the sidebar will resize when it is fully open | |
let SIDEBAR_WIDTH = -1 | |
// state enumerator, can only be closed, half-closed, and open | |
const state = { | |
closed: 0, | |
halfClosed: 1, | |
open: 2, | |
} | |
// initial state of the sidebar is open | |
let currentState = state.open | |
// waits for the sidebar to open to start the script | |
const waitForElement = (selector) => { | |
return new Promise((resolve) => { | |
const elementToLookup = document.querySelector(selector) | |
if (elementToLookup) { | |
resolve(elementToLookup) | |
} | |
new MutationObserver((_, observer) => { | |
// Query for elements matching the specified selector | |
Array.from(document.querySelectorAll(selector)).forEach((element) => { | |
resolve(element) | |
//Once we have resolved we don't need the observer anymore. | |
observer.disconnect() | |
}) | |
}).observe(document.documentElement, { | |
childList: true, | |
subtree: true, | |
}) | |
}) | |
} | |
function createExpandButton(element) { | |
const btn = document.createElement('button') | |
btn.innerHTML = | |
'<svg width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M15.2928932,12 L12.1464466,8.85355339 C11.9511845,8.65829124 11.9511845,8.34170876 12.1464466,8.14644661 C12.3417088,7.95118446 12.6582912,7.95118446 12.8535534,8.14644661 L16.8535534,12.1464466 C17.0488155,12.3417088 17.0488155,12.6582912 16.8535534,12.8535534 L12.8535534,16.8535534 C12.6582912,17.0488155 12.3417088,17.0488155 12.1464466,16.8535534 C11.9511845,16.6582912 11.9511845,16.3417088 12.1464466,16.1464466 L15.2928932,13 L4.5,13 C4.22385763,13 4,12.7761424 4,12.5 C4,12.2238576 4.22385763,12 4.5,12 L15.2928932,12 Z M19,5.5 C19,5.22385763 19.2238576,5 19.5,5 C19.7761424,5 20,5.22385763 20,5.5 L20,19.5 C20,19.7761424 19.7761424,20 19.5,20 C19.2238576,20 19,19.7761424 19,19.5 L19,5.5 Z"/></svg>' | |
Object.assign(btn.style, { | |
position: 'absolute', | |
top: '0', | |
left: '0', | |
margin: '50px 0', | |
padding: '15px 15px 15px 5px', | |
zIndex: '9999', | |
borderRadius: '0 50px 50px 0', | |
backgroundColor: '#00a884', | |
boxShadow: '10px 20px 52px 3px #037259', | |
transitionDuration: '0.3s', | |
}) | |
// add little expand animation | |
btn.addEventListener('mouseenter', () => { | |
btn.style.transform = 'scale(1.1)' | |
}) | |
btn.addEventListener('mouseleave', () => { | |
btn.style.transform = 'scale(1)' | |
}) | |
// when click on the button, show element | |
btn.addEventListener('click', () => { | |
// if it is closed, make it half open | |
if (currentState === state.closed) { | |
element.style.display = 'block' | |
currentState = state.halfClosed | |
setSideBarWidth(HALF_OPEN_WIDTH) | |
} else if (currentState === state.halfClosed) { | |
// if it is half open, make it fully open | |
currentState = state.open | |
setSideBarWidth(SIDEBAR_WIDTH) | |
btn.remove() | |
// make all divs with this data-testid "icon-unread-count" move left | |
// so that they are not hidden by the sidebar | |
const unreadCountDivs = document.querySelectorAll('[data-testid="icon-unread-count"]') | |
unreadCountDivs.forEach((div) => { | |
// move right 37px | |
div.style.left = '15px' | |
}) | |
// show the div with the _1EUay class | |
const div = document.querySelector("div[class='_1EUay']") | |
div.style.display = 'block' | |
} | |
}) | |
return btn | |
} | |
function createHideButton(element, expandBtn) { | |
const btn = document.createElement('button') | |
btn.innerHTML = | |
'<svg fill="#54656F" width="17px" heigth="17px" viewBox="-32 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"/></svg>' | |
btn.style.padding = '0 15px' | |
btn.addEventListener('click', () => { | |
if (currentState === state.open) { | |
// if side bar is open, half closes it | |
currentState = state.halfClosed | |
setSideBarWidth(HALF_OPEN_WIDTH) | |
// make all divs with this data-testid "icon-unread-count" move left | |
// so that they are not hidden by the sidebar | |
const unreadCountDivs = document.querySelectorAll('[data-testid="icon-unread-count"]') | |
unreadCountDivs.forEach((div) => { | |
// change position to relative | |
div.style.position = 'relative' | |
// move left 10 px | |
div.style.left = '-37px' | |
}) | |
// hide the div with the _1EUay class | |
const div = document.querySelector("div[class='_1EUay']") | |
div.style.display = 'none' | |
} else if (currentState === state.halfClosed) { | |
// if side bar is half open, closes it completely | |
currentState = state.closed | |
element.style.display = 'none' | |
} | |
if (!expandBtn.parentElement) | |
// create expand button | |
document.body.appendChild(expandBtn) | |
}) | |
return btn | |
} | |
waitForElement("div[class='_2Ts6i _3RGKj']").then((element) => { | |
header = element.querySelector('header') | |
// add button to header | |
expandBtn = createExpandButton(element) | |
header.appendChild(createHideButton(element, expandBtn)) | |
}) | |
function setSideBarWidth(width) { | |
const sidebar = document.querySelector("div[class='_2Ts6i _3RGKj']") | |
const mainContent = document.querySelector("div[class='_2Ts6i _2xAQV']") | |
let sidebarWidth = sidebar.clientWidth | |
if (SIDEBAR_WIDTH === -1) SIDEBAR_WIDTH = sidebarWidth | |
let mainContentWidth = mainContent.clientWidth | |
// how much sidebar has to change to get to width | |
const sidebarWidthDiff = sidebarWidth - width | |
// resize sidebar and main content | |
sidebarWidth = width | |
mainContentWidth = mainContentWidth + sidebarWidthDiff | |
// set important css for the width | |
sidebar.style.width = sidebarWidth + 'px' | |
sidebar.style.flex = '0 0 ' + sidebarWidth + 'px' | |
mainContent.style.width = mainContentWidth + 'px' | |
mainContent.style.flex = '0 0 ' + mainContentWidth + 'px' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment