Skip to content

Instantly share code, notes, and snippets.

@stanleytangerror
Last active February 25, 2024 12:41
Show Gist options
  • Select an option

  • Save stanleytangerror/45e61cfef2b6e049b7424829ab19286e to your computer and use it in GitHub Desktop.

Select an option

Save stanleytangerror/45e61cfef2b6e049b7424829ab19286e to your computer and use it in GitHub Desktop.
Countdown widget in iOS Scriptable
class ComingEvent {
constructor(name, description, countDownTime, happenTime) {
this.name = name;
this.description = description || '✏️';
this.countDownTime = countDownTime;
this.happenTime = happenTime;
}
get percentage() {
var total = this.happenTime - this.countDownTime;
var lasting = Date.now() - this.countDownTime;
return Math.max(0, lasting / total);
}
get dueDate() {
var formatter = new DateFormatter();
formatter.useMediumDateStyle();
return formatter.string(this.happenTime);
}
get remainingDays() {
return Math.ceil((this.happenTime.getTime() - Date.now()) / (1000*60*60*24));
}
}
function DaysOffset(date, days) {
return new Date(date.getTime() + days * 1000*60*60*24);
}
/////////////////////
let reminders = (await Reminder.allIncomplete())
.filter(reminder => {
return reminder.dueDate;
});
let events = reminders.map(reminder => {
return new ComingEvent(reminder.title, reminder.notes, DaysOffset(reminder.dueDate, -30), reminder.dueDate);
});
//////////////////////
let widget = createWidget();
Script.setWidget(widget);
Script.complete();
if (config.runsInApp) {
widget.presentLarge();
}
//////////////////////
function createWidget() {
var widget = new ListWidget();
widget.useDefaultPadding();
if (config.runsInApp) {
var stack = widget.addStack();
stack.layoutHorizontally();
drawEventList(stack, events.slice(0, 4));
stack.addSpacer();
drawEventList(stack, events.slice(4, 8));
}
if (config.runsInWidget) {
if (config.widgetFamily === 'small') {
var stack = widget.addStack();
stack.layoutHorizontally();
drawEventList(stack, events.slice(0, 4));
}
if (config.widgetFamily === 'medium') {
var stack = widget.addStack();
stack.layoutHorizontally();
drawEventList(stack, events.slice(0, 4));
stack.addSpacer();
drawEventList(stack, events.slice(4, 8));
}
if (config.widgetFamily === 'large') {
var stack = widget.addStack();
stack.layoutHorizontally();
drawEventList(stack, events.slice(0, 8));
stack.addSpacer();
drawEventList(stack, events.slice(8, 16));
}
if (config.widgetFamily === 'extraLarge') {
var stack = widget.addStack();
stack.layoutHorizontally();
drawEventList(stack, events.slice(0, 8));
stack.addSpacer();
drawEventList(stack, events.slice(8, 16));
stack.addSpacer();
drawEventList(stack, events.slice(16, 24));
stack.addSpacer();
drawEventList(stack, events.slice(24, 32));
}
}
return widget;
}
function drawEventList(stack, events) {
var eventStack = stack.addStack();
eventStack.layoutVertically();
for (const e of events) {
drawProgressWidget(eventStack, e);
// eventStack.addSpacer(1);
}
}
function drawProgressWidget(stack, event) {
var width = 500, height = 100;
var mainTextColor = Color.dynamic(Color.black(), Color.white());
var mainTextFont = Font.boldRoundedSystemFont(height * 0.4);
var subTextFont = Font.boldRoundedSystemFont(height * 0.2);
// Drawing Canvas
var canvas = new DrawContext();
canvas.size = new Size(width, height);
canvas.opaque = false;
canvas.respectScreenScale = true;
drawText(canvas, event.name, new Point(0, 0), mainTextColor, mainTextFont);
drawProgressBar(canvas, event.percentage, 0, height * 0.6, width * 0.4, height * 0.1);
drawText(canvas, event.dueDate, new Point(width * 0.5, height * 0.5), mainTextColor, subTextFont);
stack.addImage(canvas.getImage());
}
function drawProgressBar(canvas, percentage, barLeft, barTop, barWidth, barHeight) {
var roundSize = barHeight / 2;
// Bar Container
canvas.setFillColor(Color.dynamic(Color.darkGray(), Color.lightGray()));
var bar = new Path();
bar.addRoundedRect(
new Rect(barLeft, barTop, barWidth, barHeight),
roundSize, roundSize);
canvas.addPath(bar);
canvas.fillPath();
// Progress Bar
canvas.setFillColor(percentage > 1 ? Color.red() : Color.green());
var progress = new Path();
progress.addRoundedRect(
new Rect(barLeft, barTop, barWidth * Math.min(1, percentage), barHeight),
roundSize, roundSize
);
canvas.addPath(progress);
canvas.fillPath();
}
function drawText(canvas, text, position, color, font) {
canvas.setTextColor(color);
canvas.setFont(font);
canvas.drawText(text, position);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment