Last active
May 2, 2020 12:09
-
-
Save andregs/ce51908c80ebaaefd0cff939e564a6c8 to your computer and use it in GitHub Desktop.
Punch the clock -- see it live here: https://gist.github.com/andregs/ce51908c80ebaaefd0cff939e564a6c8#gistcomment-3269836
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
/** | |
* Bookmarklet to write my webponto e-mail message. | |
* Create a bookmark in your browser and paste this script in the 'location' field. | |
*/ | |
(function(){ | |
'use strict'; | |
const cfg = { | |
to: 'rodolfo.jesus', | |
cc: 'marco.scheid', | |
msgInicio: 'Iniciando.', | |
msgFim: 'Finalizando.', | |
}; | |
const page = { | |
btnNewMessage: 'button:contains("New message")', | |
inputTo: 'input[aria-label="To"]', | |
selectionTo: `.ms-Suggestions-itemButton div:contains('${cfg.to}'):last`, | |
inputCc: 'input[aria-label="Cc"]', | |
selectionCc: `.ms-Suggestions-itemButton div:contains('${cfg.cc}'):last`, | |
inputSubject: 'input[aria-label="Add a subject"]', | |
inputBody: '[aria-label="Message body"]>div:first-child', | |
}; | |
const alreadySent = isSentToday(); | |
/* these must be idempotent */ | |
const commandQueue = [ | |
() => { | |
$(page.btnNewMessage).click(); | |
return true; | |
}, | |
() => $(page.inputTo).length === 1, | |
() => { | |
setInputValue(page.inputTo, cfg.to); | |
return true; | |
}, | |
() => $(page.selectionTo).length === 1, | |
() => { | |
$(page.selectionTo).click(); | |
return $(page.selectionTo).length === 0; | |
}, | |
() => { | |
setInputValue(page.inputCc, cfg.cc); | |
return true; | |
}, | |
() => $(page.selectionCc).length === 1, | |
() => { | |
$(page.selectionCc).click(); | |
return $(page.selectionCc).length === 0; | |
}, | |
() => { | |
const subjectText = 'WEBPONTO WFH ' + currentTime(); | |
setInputValue(page.inputSubject, subjectText); | |
$(page.inputBody).prepend(getMessageBody(alreadySent)); | |
return true; | |
}, | |
]; | |
/** helper to change input-text value and to trigger React */ | |
function setInputValue(inputSelector, value) { | |
const proto = HTMLInputElement.prototype; | |
const setter = Object.getOwnPropertyDescriptor(proto, "value").set; | |
const input = $(inputSelector).get(0); | |
setter.call(input, value); | |
input.dispatchEvent(new Event('input', { bubbles: true })); | |
} | |
function currentTime() { | |
return (new Date()).toLocaleTimeString('pt-BR').slice(0, 5); | |
} | |
function getMessageBody(alreadySent) { | |
return alreadySent ? cfg.msgFim : cfg.msgInicio; | |
} | |
/** | |
* Helper that reads localStorage flag to determine whether | |
* webponto message was already sent today. This reading operation | |
* also switches the flag value. | |
*/ | |
function isSentToday() { | |
const today = (new Date()).toLocaleDateString('pt-BR'); | |
if (localStorage.getItem('webponto.sent') === '1' | |
&& localStorage.getItem('webponto.when') === today) { | |
localStorage.removeItem('webponto.sent'); | |
localStorage.removeItem('webponto.when'); | |
return true; | |
} else { | |
localStorage.setItem('webponto.sent', '1'); | |
localStorage.setItem('webponto.when', today); | |
return false; | |
} | |
} | |
/** | |
* Process the command queue, executing each command repeatedly untill | |
* it returns true, then advance the queue. The app finishes when the | |
* queue is empty or when it reaches max-timeout. | |
*/ | |
function executeCommands() { | |
const command = commandQueue[0]; | |
if (command) { | |
const done = command(); | |
if (done) { | |
commandQueue.shift(); | |
} | |
} else { | |
stopBot(); | |
} | |
} | |
function stopBot() { | |
clearInterval(timerHandler); | |
} | |
const heartBeat = 150; | |
const maxTimeout = 10000; | |
const timerHandler = setInterval(executeCommands, heartBeat); | |
setTimeout(stopBot, maxTimeout); | |
const weekDay = (new Date()).getDay(); | |
if (weekDay === 1 || weekDay === 5) { | |
const trailStyle = $(` | |
<style id="andregs-trail"> | |
.andregs-grid { | |
position: absolute; | |
z-index: 1; | |
display: flex; | |
flex-wrap: wrap; | |
overflow: hidden; | |
left: 0; | |
top: 0; | |
} | |
.andregs-item { | |
height: 45px; | |
width: 45px; | |
opacity: 0; | |
transition: opacity 2s ease 0.4s, transform 0.8s ease; | |
transform: scale(1); | |
font-size: 120%; | |
} | |
.andregs-item:hover { | |
opacity: 1; | |
transition: opacity 0.2s ease; | |
transform: scale(1.2); | |
} | |
</style>`); | |
function todaysMood() { | |
const moods = { | |
everyday: ['๐จโ๐ป', '๐ฉโ๐ป'], | |
monday: ['๐', '๐', '๐ด', '๐', '๐ค', '๐ค'], | |
friday: ['๐', '๐ค', '๐', '๐ต', '๐จโ๐ค', '๐ฉโ๐ค', '๐ฎ', '๐ธ', '๐บ', '๐ป', '๐', '๐โโ๏ธ'], | |
}; | |
const result = moods.everyday; | |
if (weekDay === 1) result.push(...moods.monday); | |
if (weekDay === 5) result.push(...moods.friday); | |
return result.map(a => ({sort: Math.random(), value: a})) | |
.sort((a, b) => a.sort - b.sort) | |
.map(a => a.value); | |
} | |
const myMood = todaysMood(); | |
const grid = $('<div class="andregs-grid">'); | |
for (let i = 0; i < 1000; i++) { | |
grid.append($('<div class="andregs-item">').text(myMood[i % myMood.length])); | |
} | |
clearTrail(); | |
function clearTrail() { | |
$('.andregs-grid, #andregs-trail').remove(); | |
} | |
$('body').append(trailStyle).append(grid); | |
$('.andregs-grid').click(clearTrail); | |
} | |
})(); |
Author
andregs
commented
Apr 26, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment