Last active
November 4, 2020 02:42
-
-
Save brainno722/e17948153402965f2d24b5b9e6d18bc1 to your computer and use it in GitHub Desktop.
Scriptable - Another calendar widget with holidays
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
// Variables used by Scriptable. | |
// These must be at the very top of the file. Do not edit. | |
// icon-color: red; icon-glyph: calendar; | |
const spaceDays = 6 | |
const dayFont = new Font('verdana', 10) | |
const dayColor = new Color('#000') | |
const todayColor = new Color('#fff') | |
const todayHilite = new Color('#000') | |
const dayXColor = new Color('#555', 0.5) | |
const monthColor = new Color('#CC3F0C') | |
const yearColor = new Color('#9A6D38') | |
const daySpColor = new Color('#000', 0.5) | |
// Icon made by Freepik from www.flaticon.com | |
let FORCE_IMAGE_UPDATE = false | |
async function getImage(url, fileName) { | |
let files = FileManager.iCloud() | |
const path = files.joinPath(files.documentsDirectory(), 'holidayCal/' + fileName + '.png') | |
let hasImage = files.fileExists(path) | |
let holidayImg | |
if (FORCE_IMAGE_UPDATE || !hasImage) { | |
holidayImg = await getBG(url) | |
files.writeImage(path,holidayImg) | |
console.log('fetched: '+path) | |
} | |
else { | |
holidayImg = files.readImage(path) | |
console.log('no fetch') | |
} | |
return holidayImg | |
} | |
let thisDay = new Date() | |
let thisDayDate = thisDay.getDate() | |
let thisMonth = thisDay.getMonth() | |
let thisYear = thisDay.getFullYear() | |
let firstWkdayOfMonth = ( | |
new Date(`${thisYear}-${thisMonth + 1}-01`).getDay() | |
) | |
//testing only | |
/* | |
let thisDay = new Date('2020-02-08') | |
let firstWkdayOfMonth = 6 | |
let thisDayDate = 15 | |
let thisMonth = 7 | |
let thisYear = 2020 | |
*/ | |
let februaryDays = (leapYear(thisDay.getFullYear())) ? 29 : 28; | |
let months = [ | |
{'name': 'january', 'days': 31, 'holidays': [{'date':'1', 'event': 'newyear', 'url': 'https://i.ibb.co/4fd1Y6Z/confetti.png'}]}, | |
{'name': 'february', 'days': februaryDays, 'holidays': [{'date': '14', 'event': 'valentine', 'url':'https://i.ibb.co/vPyr7fv/lover-2.png'}]}, | |
{'name': 'march', 'days': 31, 'holidays': []}, | |
{'name': 'april', 'days': 30, 'holidays': [{'date':'5', 'event': 'easter', 'url':'https://i.ibb.co/yn4bK70/easter-egg.png'}]}, | |
{'name': 'may', 'days':31, 'holidays': [{'date':'3', 'event':'maybank1', 'url':'https://i.ibb.co/yBJqTXs/cocktail-drink.png'}, {'date':'31', 'event':'maybank2', 'url': 'https://i.ibb.co/v3nRwDZ/surfboard.png'}]}, | |
{'name': 'june', 'days':30,'holidays': []}, | |
{'name': 'july', 'days':31, 'holidays': [{'date':'4', 'event':'usa', 'url': 'https://i.ibb.co/KyJS759/usa.png'}]}, | |
{'name': 'august', 'days':31, 'holidays': [{'date':'30', 'event': 'augustbank', 'url': 'https://i.imgur.com/dNuAWYk.png', 'author': 'Smashicons'}]}, | |
{'name': 'september', 'days':30,'holidays': []}, | |
{'name': 'october', 'days':31,'holidays': [{'date':'31', 'event': 'pumpkin', 'url':'https://i.ibb.co/rx0Bchd/pumpkin.png'}]}, | |
{'name': 'november', 'days':30,'holidays': [{'date':'26', 'event': 'turkey', 'url': 'https://i.ibb.co/VD8Q2bb/turkey.png'}]}, | |
{'name': 'december', 'days':31,'holidays': [{'date':'25', 'event': 'xmas', 'url': 'https://i.ibb.co/fNPwjrY/christmas-wreath.png', 'author': 'iconixar'}]} | |
] | |
const spaceMonthYear = months[thisMonth].name.length < 5 ? 40: 10 | |
// Choose Sunday first wkdays[0] or Monday first | |
const weekDays = [ | |
[0, ['S', 'M', 'T', 'W', 'T', 'F', 'S']], | |
[1, ['M', 'T', 'W', 'T', 'F', 'S', 'S']] | |
] | |
let wkDayFirst = weekDays[1] | |
let mondayOffset = wkDayFirst[0] ? firstWkdayOfMonth - 1 : firstWkdayOfMonth | |
if (mondayOffset < 0) {mondayOffset = 6} | |
let prevMonth = ((thisMonth - 1) < 0) ? 11 : (thisMonth - 1) | |
let prevMonthTotalDays = months[prevMonth].days | |
let prevMonthDays = [] | |
for (let i = 0; i < mondayOffset; i++) { | |
prevMonthDays.push(prevMonthTotalDays - i) | |
} | |
let showPrevMdays = prevMonthDays.reverse() | |
let daysInMonth = months[thisMonth].days | |
let widget = new ListWidget() | |
widget.setPadding(0, 7, 0, 0) | |
widget.backgroundColor = new Color('#fff', 1) | |
let monthYearRow = widget.addStack() | |
monthYearRow.layoutHorizontally() | |
let monthTxt = monthYearRow.addText(months[thisMonth].name.toUpperCase()) | |
monthTxt.textColor = monthColor | |
monthYearRow.addSpacer(spaceMonthYear) | |
let yearTxt = monthYearRow.addText(thisYear.toString()) | |
yearTxt.textColor = yearColor | |
widget.addSpacer(10) | |
wkDayRow = widget.addStack() | |
wkDayRow.layoutHorizontally() | |
wkDayRow.setPadding(0, 2, 0, 0) | |
for (let i = 0; i < 7; i++) { | |
let wkdayTxt = wkDayRow.addText(wkDayFirst[1][i]) | |
wkdayTxt.font = dayFont | |
wkdayTxt.textColor = dayColor | |
wkdayTxt.centerAlignText() | |
wkDayRow.addSpacer(13) | |
} | |
row1 = widget.addStack() | |
row2 = widget.addStack() | |
row3 = widget.addStack() | |
row4 = widget.addStack() | |
row5 = widget.addStack() | |
row6 = widget.addStack() | |
let dayOne = 1 | |
let strThisMonth = thisMonth.toString() | |
let hasHolidays = months[thisMonth].holidays | |
for (let i = 0; i < daysInMonth + mondayOffset; i++) { | |
if (i < mondayOffset) { | |
addDaysRow(showPrevMdays[i].toString(), dayXColor, row1, img=false, prev=true) | |
row1.addSpacer(spaceDays) | |
dayOne-- | |
} | |
else { | |
let strDayOne = dayOne.toString() | |
if (i < 7) { | |
makeHoliday(strDayOne, row1) | |
row1.addSpacer(spaceDays) | |
} | |
else if (i < 14) { | |
makeHoliday(strDayOne, row2) | |
row2.addSpacer(spaceDays) | |
} | |
else if (i < 21) { | |
makeHoliday(strDayOne, row3) | |
row3.addSpacer(spaceDays) | |
} | |
else if (i < 28){ | |
makeHoliday(strDayOne, row4) | |
row4.addSpacer(spaceDays) | |
} | |
else if (i < 28+7) { | |
makeHoliday(strDayOne, row5) | |
row5.addSpacer(spaceDays) | |
} | |
else { | |
makeHoliday(strDayOne, row6) | |
row6.addSpacer(spaceDays) | |
} | |
} | |
dayOne++ | |
} | |
async function makeHoliday (strDay, row) { | |
let holidayImgInfo = months[strThisMonth].holidays.filter(holidayObj => holidayObj.date === strDay); | |
let hasEvent = holidayImgInfo[0] | |
if (hasEvent === undefined){ | |
addDaysRow(strDay, dayColor, row) | |
} | |
else { | |
let holidayImg = await getImage(holidayImgInfo[0].url, holidayImgInfo[0].event) | |
addDaysRow(strDay, Color.darkGray(), row, holidayImg) | |
} | |
} | |
function addDaysRow(dayNum, color, row, img=false, prev=false) { | |
let s = row.addStack() | |
s.layoutHorizontally() | |
s.size = new Size(15, 15) | |
if (dayNum == thisDayDate && !prev && !img) { | |
const highlightedDate = dayHighlight(dayNum, todayColor, todayHilite) | |
s.addImage(highlightedDate); | |
} | |
else if (img) { | |
let holidayImg = daySpecial(dayNum, color, img) | |
s.addImage(holidayImg) | |
} | |
else { | |
let dayShow = s.addText(dayNum) | |
dayShow.font = dayFont | |
dayShow.textColor = color | |
dayShow.centerAlignText() | |
} | |
} | |
function leapYear(year) { | |
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); | |
} | |
function dayHighlight(day, dayColor, hilite) { | |
const drawToday = new DrawContext(); | |
const size = 35; | |
drawToday.size = new Size(size, size); | |
drawToday.opaque = false; | |
drawToday.setFillColor(hilite); | |
drawToday.fillEllipse(new Rect(2, 0, size-2, size-2)); | |
drawToday.setFont(new Font('verdana', 25)); | |
drawToday.setTextAlignedCenter(); | |
drawToday.setTextColor(dayColor); | |
drawToday.drawTextInRect(day, new Rect(1, -1, size, size)); | |
const currentDayImg = drawToday.getImage(); | |
return currentDayImg; | |
} | |
function daySpecial(day, spColor, img) { | |
const drawSpecial = new DrawContext(); | |
const size = 35; | |
drawSpecial.size = new Size(size, size); | |
drawSpecial.opaque = false; | |
drawSpecial.setFont(new Font('verdana', 25)); | |
drawSpecial.setTextAlignedCenter(); | |
drawSpecial.drawImageInRect(img, new Rect(0, 0, size, size)) | |
drawSpecial.setTextColor(spColor); | |
drawSpecial.drawTextInRect(day, new Rect(0, 0, size, size)); | |
const currentDayImg = drawSpecial.getImage(); | |
return currentDayImg; | |
} | |
async function getBG(url) { | |
let imgReq = new Request(url) | |
return await imgReq.loadImage() | |
} | |
Script.setWidget(widget) | |
Script.complete() | |
if (config.runsInWidget) { | |
widget.presentSmall() | |
} else { | |
widget.presentSmall() | |
} |
Author
brainno722
commented
Oct 15, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment