Skip to content

Commit

Permalink
Edit snooze times for sleeping tabs from the dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
rohanb10 committed May 15, 2021
1 parent 03a5f51 commit 516c77a
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 47 deletions.
2 changes: 2 additions & 0 deletions html/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<img class="snoozz-text" src="../icons/snoozz.png">
</div>
<div tabindex="0" data-hover="Settings" class="settings"><img src="../icons/settings.svg"></div>
<div class="iframe-overlay"></div>
<div class="instructions hidden">
<img class="up-arrow" src="../icons/up-arrow.svg">
<div>Snoozz a tab/window using the pop-up menu above.</div><br>
Expand Down Expand Up @@ -56,6 +57,7 @@
<p id="history-message">Tabs in your Snoozz history are removed <a id="historyHref" href="./settings.html#history">-</a> after they wake up.</p>
<script type="text/javascript" src="../scripts/dayjs.min.js"></script>
<script type="text/javascript" src="../scripts/common.js"></script>
<script type="text/javascript" src="../scripts/bodyScrollFreezer.js"></script>
<script type="text/javascript" src="../scripts/gradientStep.js"></script>
<script type="text/javascript" src="../scripts/dashboard.js"></script>
</body>
Expand Down
Binary file added icons/edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions scripts/bodyScrollFreezer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 21 additions & 2 deletions scripts/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ async function saveOptions(o) {
async function saveTab(t) {
if (!t) return;
var tabs = await getSnoozedTabs();
tabs.push(t);
if (tabs.some(tab => tab.id == t.id)) {
tabs[tabs.findIndex(tab => tab.id == t.id)] = t;
} else {
tabs.push(t);
}
await saveTabs(tabs);
}
async function saveTabs(tabs) {
Expand Down Expand Up @@ -173,6 +177,16 @@ async function openWindow(t, automatic = false) {
return;
}

async function editSnoozeTime(tabId, snoozeTime) {
var t = await getSnoozedTabs(tabId);
if (t.opened) return {};
delete t.startUp;
t.wakeUpTime = snoozeTime == 'startup' ? dayjs().add(20, 'y').valueOf() : dayjs(snoozeTime).valueOf(),
t.modifiedTime = dayjs().valueOf();
await saveTab(t);
return {edited: true}
}

/* SNOOZING */
async function snoozeTab(snoozeTime, overrideTab) {
var activeTab = overrideTab || await getTabsInWindow(true);
Expand Down Expand Up @@ -274,7 +288,7 @@ async function getChoices(which) {
config.timeOfDay = config.timeOfDay === 'evening' ? config.evening : (config.timeOfDay === 'morning' ? config.morning : NOW.hour() + (NOW.minute() / 60))
var all = {
'startup': {
label: 'On Startup',
label: 'On Next Startup',
startUp: true,
time: NOW.add(20, 'y'),
timeString: ' ',
Expand Down Expand Up @@ -389,6 +403,11 @@ var clipboard = text => {
document.execCommand('copy'); el.remove();
}

var getUrlParam = p => {
var url = new URLSearchParams(window.location.search);
return url.get(p);
}

var bgLog = (logs, colors, timestampColor = 'grey') => {
var timestamp = dayjs().format('[%c]DD/MM/YY HH:mm:ss[%c] | ')
logs = logs.map(l => '%c'+l+'%c').join(' ')
Expand Down
56 changes: 51 additions & 5 deletions scripts/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,9 @@ function search(t, query) {
if (t.url && t.url.toLowerCase().indexOf(query) > -1) return true;
if (t.title && t.title.toLowerCase().indexOf(query) > -1) return true;
// relative time
if (t.startUp && !t.opened && ('start starting launch launching next time open opening').indexOf(query) > -1) return true;
if (!t.opened && ('snoozed sleeping asleep napping snoozzed snoozing snoozzing').indexOf(query) > -1) return true;
if (t.opened && ('manually deleted removed reopened awake history').indexOf(query) > -1) return true;
if (t.opened && ('manually deleted removed woke awake history').indexOf(query) > -1) return true;
// categories
if (matchQuery(query, getTimeGroup(t, 'wakeUpTime', true).map(tg => tg.replace(/_/g, ' ')))) return true;
if (matchQuery(query, getTimeGroup(t, 'timeCreated', true).map(tg => tg.replace(/_/g, ' ')))) return true;
Expand All @@ -196,6 +197,7 @@ function buildTabActions(t, tabDiv) {
tabDiv = tabDiv || document.getElementById(t.id);

var tabName = tabDiv.querySelector('.tab-name');
var editBtn = tabDiv.querySelector('img.edit-button');
var wakeUpBtn = tabDiv.querySelector('img.wakeup-button');
var removeBtn = tabDiv.querySelector('img.remove-button');

Expand All @@ -206,14 +208,17 @@ function buildTabActions(t, tabDiv) {
tabName.onkeyup = e => { if (e.which === 13) openTab(t)};
}
wakeUpBtn.remove();
editBtn.remove();
removeBtn.remove();

var newRemoveBtn = Object.assign(document.createElement('img'), {className:'remove-button', src: '../icons/close.svg', tabIndex: 0});
newRemoveBtn.onclick = async _ => await removeTabsFromHistory([t.id])
newRemoveBtn.onkeyup = async e => {if (e.which === 13) await removeTabsFromHistory([t.id])}
tabDiv.querySelector('.remove-btn-container').append(newRemoveBtn)
} else {
wakeUpBtn.onclick = async _ => await wakeUpTabsAbruptly([t.id])
editBtn.onclick = _ => openEditModal(t.id);
editBtn.onkeyup = e => {if (e.which === 13) openEditModal(t.id)}
wakeUpBtn.onclick = async _ => await wakeUpTabsAbruptly([t.id]);
wakeUpBtn.onkeyup = async e => {if (e.which === 13) await wakeUpTabsAbruptly([t.id])}
removeBtn.onclick = async _ => await sendTabsToHistory([t.id])
removeBtn.onkeyup = async e => {if (e.which === 13) await sendTabsToHistory([t.id])}
Expand Down Expand Up @@ -259,14 +264,18 @@ function buildTab(t) {
[iconContainer, titleContainer].forEach(c => c.addEventListener('click', _ => tab.classList.toggle('collapsed')))
iconContainer.onkeyup = e => {if (e.which === 13) tab.classList.toggle('collapsed')}
}
var editBtn = Object.assign(document.createElement('img'), {className:'edit-button', src: '../icons/edit.png', tabIndex: 0});
var editBtnContainer = wrapInDiv('edit-btn-container tooltip', editBtn)

var wakeUpBtn = Object.assign(document.createElement('img'), {className:'wakeup-button', src: '../icons/sun.png', tabIndex: 0});
var wakeUpBtnContainer = wrapInDiv('wakeup-btn-container tooltip', wakeUpBtn)

var removeBtn = Object.assign(document.createElement('img'), {className:'remove-button', src: '../icons/close.svg', tabIndex: 0});
var removeBtnContainer = wrapInDiv('remove-btn-container tooltip', removeBtn)

tab.append(iconContainer, titleContainer, wakeUpTimeContainer, wakeUpBtnContainer, removeBtnContainer, littleTabs);
// tab.addEventListener('click', _ => openEditModal(t.id));

tab.append(iconContainer, titleContainer, wakeUpTimeContainer, editBtnContainer, wakeUpBtnContainer, removeBtnContainer, littleTabs);
return tab;
}

Expand All @@ -282,21 +291,58 @@ function formatSnoozedUntil(ts) {

function getTimeGroup(tab, timeType = 'wakeUpTime', searchQuery = false) {
if (!searchQuery && tab.opened) return 'history';
if (!searchQuery && tab.startUp) return 'next_startup';

var group = [];
if (!tab.opened && !tab[timeType]) return group;
var now = dayjs(), time = searchQuery && tab.opened ? dayjs(tab.opened) : dayjs(tab[timeType]);
if (tab.startUp) group.push('next_startup');
// if (tab.startUp) group.push('next_startup');
if (time.week() === now.subtract(1, 'week').week()) group.push('last_week');
if (time.dayOfYear() === now.subtract(1, 'd').dayOfYear()) group.push('yesterday');
if (time.dayOfYear() === now.dayOfYear() && time.year() == now.year()) group.push('today');
if (time.dayOfYear() === now.dayOfYear()) group.push('today');
if (time.dayOfYear() === now.add(1, 'd').dayOfYear()) group.push('tomorrow');
if (time.week() === now.week()) group.push('this_week');
if (time.week() === now.add(1, 'week').week()) group.push('next_week');
if (time.valueOf() > now.add(1, 'week').valueOf()) group.push('later');
return searchQuery ? group : group[0];
}

function openEditModal(tabId) {
var overlay = document.querySelector('body > .iframe-overlay');
overlay.style.top = window.scrollY + 'px';
var iframe = document.createElement('iframe');
iframe.src = './popup.html?edit=true&tabId=' + tabId;
iframe.setAttribute('scrolling', 'no');
overlay.append(iframe);
overlay.classList.add('open');
bodyScrollFreezer.freeze();
overlay.addEventListener('click', closeOnOutsideClick, {once: true});
document.addEventListener('keyup', closeOnOutsideClick);
}
function deleteTabFromDiv(tabId) {
document.getElementById(tabId).outerHTML = '';
}

function closeOnOutsideClick(e) {
if (e.which && e.which == 27) closeEditModal();
if(e.target && e.target.classList.contains('iframe-overlay')) closeEditModal();
}

function resizeIframe() {
var frame = document.querySelector('body > .iframe-overlay > iframe');
frame.style.height = frame.contentWindow.document.documentElement.scrollHeight + 'px';
}

function closeEditModal() {
var overlay = document.querySelector('body > .iframe-overlay');
overlay.removeEventListener('click', closeOnOutsideClick);
document.removeEventListener('keyup', closeOnOutsideClick);
overlay.classList.remove('open');
overlay.querySelector('iframe').remove();
overlay.style.top = '';
bodyScrollFreezer.unfreeze()
}

async function wakeUpTabsAbruptly(ids) {
if (!ids) return;
CACHED_TABS.filter(t => ids.includes(t.id)).forEach(t => t.opened = dayjs().valueOf())
Expand Down
46 changes: 33 additions & 13 deletions scripts/popup.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
var collapse, customChoice, closeDelay = 1000, colorList = [];
var closeDelay = 1000, colorList = [], isInEditMode = false, editTabId;
async function init() {
isInEditMode = getUrlParam('edit') && getUrlParam('edit') == 'true';

await buildChoices();
buildCustomChoice();
await buildTargets();
if (isInEditMode) {
initEditMode();
} else {
await buildTargets();
}

document.querySelectorAll('.dashboard-btn, .settings').forEach(btn => btn.addEventListener('click', el => {
openExtensionTab(el.target.dataset.href);
Expand All @@ -22,7 +28,7 @@ async function init() {

closeDelay = await getOptions('closeDelay');
var tabs = await getSnoozedTabs();
if (tabs && tabs.length) {
if (!isInEditMode && tabs && tabs.length) {
var todayCount = sleeping(tabs).filter(t => dayjs(t.wakeUpTime).dayOfYear() === dayjs().dayOfYear()).length;
if (todayCount > 0) document.querySelector('.upcoming').setAttribute('data-today', todayCount);
}
Expand All @@ -44,7 +50,15 @@ async function init() {
if (e.which === 87) document.getElementById('window').click();
if (e.which === 83) document.getElementById('selection').click();
if (e.which === 71) document.getElementById('group').click();
})
});
if (isInEditMode && parent && parent.resizeIframe) parent.resizeIframe();
}
async function initEditMode() {
document.getElementById('targets').remove();
document.querySelector('.footer').remove();
var t = await getSnoozedTabs(getUrlParam('tabId'));
document.getElementById('preview-text').innerText = t.title;
document.getElementById('preview-favicon').src = t.tabs ? '../icons/window.png' : t.favicon && t.favicon.length ? t.favicon : getFaviconUrl(t.url);
}

async function buildTargets() {
Expand Down Expand Up @@ -106,16 +120,16 @@ async function generatePreview(type) {
} else if (type == 'window') {
var validTabs = allTabs.filter(t => !isDefault(t) && isValid(t));
previewText.innerText = `${getTabCountLabel(validTabs)} from ${getSiteCountLabel(validTabs)}`;
previewIcon.src = '../icons/octopus.png'
previewIcon.src = '../icons/window.png';
} else if (type == 'selection') {
var validTabs = allTabs.filter(t => !isDefault(t) && isValid(t) && t.highlighted);
previewText.innerText = `${validTabs.length} selected tabs from ${getSiteCountLabel(validTabs)}`;
previewIcon.src = '../icons/magnet.png'
previewIcon.src = '../icons/magnet.png';
} else if (type == 'group') {
var currentTabGroup = allTabs.find(at => at.active).groupId;
var validTabs = allTabs.filter(t => currentTabGroup && currentTabGroup != -1 && !isDefault(t) && isValid(t) && t.groupId && t.groupId == currentTabGroup);
previewText.innerText = `${validTabs.length} grouped tabs from ${getSiteCountLabel(validTabs)}`;
previewIcon.src = '../icons/octopus.png'
previewIcon.src = '../icons/octopus.png';
} else {
previewText.innerText = `Can't snooze this tab`;
}
Expand Down Expand Up @@ -235,10 +249,16 @@ function buildCustomChoice() {
validate();
}

var activateForm = (a = true) => {customChoice.classList.toggle('active', a); clearTimeout(collapse)}
var focusForm = (f = true) => {customChoice.classList.toggle('focused', f); clearTimeout(collapse)}

async function modify(time, choice) {
if (!isInEditMode || !getUrlParam('tabId')) return;
if (parent && parent.deleteTabFromDiv) parent.deleteTabFromDiv(getUrlParam('tabId'))
var response = await editSnoozeTime(getUrlParam('tabId'), time);
if (!response || !response.edited) return;
displayPreviewAnimation(choice, 'Going back to sleep');
if (parent && parent.closeEditModal) setTimeout(_ => parent.closeEditModal(), closeDelay);
}
async function snooze(time, choice) {
if (isInEditMode) return modify(time, choice);
var target = document.querySelector('.target.active');
if (!['tab', 'window', 'selection', 'group'].includes(target.id)) return;

Expand All @@ -254,16 +274,16 @@ async function snooze(time, choice) {
}
if (response && !(response.tabId || response.windowId)) return;
await chrome.runtime.sendMessage(Object.assign(response, {close: true, delay: closeDelay}));
displayPreviewAnimation(choice, target.id)
displayPreviewAnimation(choice, `Snoozing ${target.id}`)
}
function displayPreviewAnimation(choice, type) {
function displayPreviewAnimation(choice, text = 'Snoozing') {
document.body.style.pointerEvents = 'none';
choice.classList.add('focused');
var preview = document.getElementById('preview');
preview.classList.add('snoozed');
preview.textContent = '';
preview.appendChild(Object.assign(document.createElement('span'), {
textContent: `Snoozing ${type}`,
textContent: text,
style: {
transition: `color 400ms ease-in-out ${(closeDelay/2) - 250}ms`,
color: '#000',
Expand Down
Loading

0 comments on commit 516c77a

Please sign in to comment.