Skip to content

Instantly share code, notes, and snippets.

@brainno722
Last active November 4, 2020 02:42
Show Gist options
  • Save brainno722/e17948153402965f2d24b5b9e6d18bc1 to your computer and use it in GitHub Desktop.
Save brainno722/e17948153402965f2d24b5b9e6d18bc1 to your computer and use it in GitHub Desktop.
Scriptable - Another calendar widget with holidays
// 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()
}
@brainno722
Copy link
Author

File (3)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment