Created
June 5, 2021 13:54
-
-
Save icsAT/5f4136d53e379a7a343e65ad59f39a44 to your computer and use it in GitHub Desktop.
Einfaches Skript zur Darstellung der Uhrzeit in Textform in einem Scriptable Widget.
This file contains 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: light-gray; icon-glyph: magic; | |
// Quelle: https://gist.github.com/icsAT | |
// Version 0.80 vom 05.06.2021 | |
// Die Idee zu dieser Widget Germanisierung stammt aus der Facebook Gruppe "Scriptable ios" | |
// von Oliver Shmith, der jemanden gesucht hat, der ein englischsprechiges Widget auf | |
// deutsch umbaut. | |
// Die Version 2 highlighted einzelne Buchstaben, statt ganze Worte. Dadurch ist die Optik harmonischer. | |
// Als Basis diente das Skript "WorldClockWidget" von Linda Zheng. | |
// Das Original findet man hier: | |
// https://github.com/yaylinda/scriptable/blob/main/WordClockWidget.js | |
/*========================================================= | |
* WIDGET CONFIGURATIONS | |
========================================================*/ | |
const WIDGET_CONFIGURATIONS = { | |
// If this is true, it opens a prompt to select a | |
// background image from the photo gallery, | |
// when the widget is run from the Scriptable app | |
useBackgroundImage: true, | |
// If useBackgroundImage is set to false, this background | |
// color gradient will be use. Feel free to set to your | |
// own colors | |
backgroundColor: [ | |
new Color("#29323c"), | |
new Color("#1c1c1c") | |
], | |
// The font to use for the words in the word clock | |
font: 'Menlo-Bold', | |
// The font size to use for the words in the word clock | |
fontSize: 12, | |
// The color to use for the "highlighted" words. | |
// The "highlighted" words tells the time | |
textColorHighlighted: Color.white(), | |
// The color of the highlighted text shadow | |
textShadowHighlighted: Color.cyan(), | |
// The radius of the highlighted text shadow | |
textShadowHighlightedRadius: 3, | |
// The color of the words that are NOT highlighted | |
textColorBackground: Color.lightGray(), | |
// The opacity of the non-highlighted words | |
// 1 -> opaque; 0 -> transparent | |
textAlphaBackground: 0.5, | |
// The spacing between the lines of words of the clock | |
spacingBetweenLines: 3, | |
// The spacing between each individual word, within the | |
// same line | |
spacingBetweenWords: 2, | |
} | |
/*========================================================= | |
* WIDGET SET UP / PRESENTATION | |
========================================================*/ | |
/** | |
* The words to display for the clock. If you want to use | |
* other words, make sure to update getHighlightedWords() | |
* accordingly. | |
*/ | |
const TIME_WORDS_MATRIX = [ | |
['E', 'S', 'T', 'I', 'S', 'T', 'I', 'M', 'E', 'I', 'N', 'E'], | |
['V', 'I', 'E', 'R', 'T', 'E', 'L', 'A', 'Z', 'E', 'H', 'N'], | |
['Z', 'W', 'A', 'N', 'Z', 'I', 'G', 'F', 'Ü', 'N', 'F', 'N'], | |
['N', 'A', 'C', 'H', 'V', 'O', 'R', 'D', 'H', 'A', 'L', 'B'], | |
['D', 'A', 'T', 'Z', 'W', 'Ö', 'L', 'F', 'E', 'I', 'N', 'S'], | |
['Z', 'W', 'E', 'I', 'D', 'R', 'E', 'I', 'V', 'I', 'E', 'R'], | |
['F', 'Ü', 'N', 'F', 'S', 'E', 'C', 'H', 'S', 'E', 'L', 'F'], | |
['S', 'I', 'E', 'B', 'E', 'N', 'E', 'A', 'C', 'H', 'T', 'T'], | |
['N', 'E', 'U', 'N', 'I', 'Z', 'E', 'H', 'N', 'U', 'H', 'R'], | |
]; | |
const widget = new ListWidget(); | |
await setBackground(widget, WIDGET_CONFIGURATIONS); | |
drawWidget(widget, WIDGET_CONFIGURATIONS); | |
if (config.runsInWidget) { | |
Script.setWidget(widget); | |
Script.complete(); | |
} else { | |
Script.setWidget(widget); | |
widget.presentSmall(); | |
Script.complete(); | |
} | |
/*========================================================= | |
* FUNCTIONS | |
========================================================*/ | |
/** | |
* Main widget rendering function. | |
* | |
* Lays out the widget as a vertical list of stacks, | |
* containing texts. | |
*/ | |
function drawWidget(widget, { | |
font, | |
fontSize, | |
textColorHighlighted, | |
textShadowHighlighted, | |
textShadowHighlightedRadius, | |
textColorBackground, | |
textAlphaBackground, | |
spacingBetweenLines, | |
spacingBetweenWords, | |
}) { | |
const mainStack = widget.addStack(); | |
mainStack.layoutVertically(); | |
mainStack.spacing = spacingBetweenLines; | |
const highlightedWords = getHighlightedWords(); | |
for (let i = 0; i < TIME_WORDS_MATRIX.length; i++) { | |
const numWords = TIME_WORDS_MATRIX[i].length; | |
const textStack = mainStack.addStack(); | |
textStack.layoutHorizontally(); | |
textStack.spacing = spacingBetweenWords; | |
for (let j = 0; j < numWords; j++) { | |
const text = textStack.addText(TIME_WORDS_MATRIX[i][j]); | |
text.font = new Font(font, fontSize); | |
if (highlightedWords[i] && highlightedWords[i][j]) { | |
text.textColor = textColorHighlighted; | |
text.shadowColor = textShadowHighlighted; | |
text.shadowRadius = textShadowHighlightedRadius; | |
} else { | |
text.textColor = textColorBackground; | |
text.alpha = textAlphaBackground; | |
} | |
} | |
} | |
} | |
/** | |
* Based on the input time, returns an array of arrays of | |
* which "time" words should be highlighted. | |
* | |
* This is used as a look-up when adding texts to the | |
* stack. | |
*/ | |
function getHighlightedWords() { | |
// The dimensions of this should match the dimensions of | |
// TIME_WORDS_MATRIX | |
const defaultHighlights = [ | |
[true, true, false, true, true, true, false, false, false, false, false, false], | |
[false, false, false, false, false, false, false, false, false, false, false, false], | |
[false, false, false, false, false, false, false, false, false, false, false, false], | |
[false, false, false, false, false, false, false, false, false, false, false, false], | |
[false, false, false, false, false, false, false, false, false, false, false, false], | |
[false, false, false, false, false, false, false, false, false, false, false, false], | |
[false, false, false, false, false, false, false, false, false, false, false, false], | |
[false, false, false, false, false, false, false, false, false, false, false, false], | |
[false, false, false, false, false, false, false, false, false, false, false, false], | |
]; | |
const date = new Date(); | |
let hour = date.getHours(); | |
const minute = date.getMinutes(); | |
if (minute >= 25) { | |
// increment hour | |
hour = hour + 1; | |
} | |
if (minute >= 0 && minute < 5) { | |
// highlight "uhr" | |
defaultHighlights[8][9] = true; | |
defaultHighlights[8][10] = true; | |
defaultHighlights[8][11] = true; | |
} else if (minute >= 5 && minute < 10) { | |
// highlight "fünf" | |
defaultHighlights[2][7] = true; | |
defaultHighlights[2][8] = true; | |
defaultHighlights[2][9] = true; | |
defaultHighlights[2][10] = true; | |
// highlight "nach" | |
defaultHighlights[3][0] = true; | |
defaultHighlights[3][1] = true; | |
defaultHighlights[3][2] = true; | |
defaultHighlights[3][3] = true; | |
} else if (minute >= 10 && minute < 15) { | |
// highlight "zehn" | |
defaultHighlights[1][8] = true; | |
defaultHighlights[1][9] = true; | |
defaultHighlights[1][10] = true; | |
defaultHighlights[1][11] = true; | |
/// highlight "nach" | |
defaultHighlights[3][0] = true; | |
defaultHighlights[3][1] = true; | |
defaultHighlights[3][2] = true; | |
defaultHighlights[3][3] = true; | |
} else if (minute >= 15 && minute < 20) { | |
// highlight "virtel" | |
defaultHighlights[1][0] = true; | |
defaultHighlights[1][1] = true; | |
defaultHighlights[1][2] = true; | |
defaultHighlights[1][3] = true; | |
defaultHighlights[1][4] = true; | |
defaultHighlights[1][5] = true; | |
defaultHighlights[1][6] = true; | |
// highlight "nach" | |
defaultHighlights[3][0] = true; | |
defaultHighlights[3][1] = true; | |
defaultHighlights[3][2] = true; | |
defaultHighlights[3][3] = true; | |
} else if (minute >= 20 && minute < 25) { | |
// highlight "zwanzig" | |
defaultHighlights[2][0] = true; | |
defaultHighlights[2][1] = true; | |
defaultHighlights[2][2] = true; | |
defaultHighlights[2][3] = true; | |
defaultHighlights[2][4] = true; | |
defaultHighlights[2][5] = true; | |
defaultHighlights[2][6] = true; | |
// highlight "nach" | |
defaultHighlights[3][0] = true; | |
defaultHighlights[3][1] = true; | |
defaultHighlights[3][2] = true; | |
defaultHighlights[3][3] = true; | |
} else if (minute >= 25 && minute < 30) { | |
// highlight "fünf" | |
defaultHighlights[2][7] = true; | |
defaultHighlights[2][8] = true; | |
defaultHighlights[2][9] = true; | |
defaultHighlights[2][10] = true; | |
// highlight "vor" | |
defaultHighlights[3][4] = true; | |
defaultHighlights[3][5] = true; | |
defaultHighlights[3][6] = true; | |
// highlight "halb" | |
defaultHighlights[3][8] = true; | |
defaultHighlights[3][9] = true; | |
defaultHighlights[3][10] = true; | |
defaultHighlights[3][11] = true; | |
} else if (minute >= 30 && minute < 35) { | |
// highlight "halb" | |
defaultHighlights[3][8] = true; | |
defaultHighlights[3][9] = true; | |
defaultHighlights[3][10] = true; | |
defaultHighlights[3][11] = true; | |
} else if (minute >= 35 && minute < 40) { | |
// highlight "fünf" | |
defaultHighlights[2][7] = true; | |
defaultHighlights[2][8] = true; | |
defaultHighlights[2][9] = true; | |
defaultHighlights[2][10] = true; | |
// highlight "nach" | |
defaultHighlights[3][0] = true; | |
defaultHighlights[3][1] = true; | |
defaultHighlights[3][2] = true; | |
defaultHighlights[3][3] = true; | |
// highlight "halb" | |
defaultHighlights[3][8] = true; | |
defaultHighlights[3][9] = true; | |
defaultHighlights[3][10] = true; | |
defaultHighlights[3][11] = true; | |
} else if (minute >= 40 && minute < 45) { | |
// highlight "zwanzig" | |
defaultHighlights[2][0] = true; | |
defaultHighlights[2][1] = true; | |
defaultHighlights[2][2] = true; | |
defaultHighlights[2][3] = true; | |
defaultHighlights[2][4] = true; | |
defaultHighlights[2][5] = true; | |
defaultHighlights[2][6] = true; | |
// highlight "vor" | |
defaultHighlights[3][4] = true; | |
defaultHighlights[3][5] = true; | |
defaultHighlights[3][6] = true; | |
} else if (minute >= 45 && minute < 50) { | |
// highlight "virtel" | |
defaultHighlights[1][0] = true; | |
defaultHighlights[1][1] = true; | |
defaultHighlights[1][2] = true; | |
defaultHighlights[1][3] = true; | |
defaultHighlights[1][4] = true; | |
defaultHighlights[1][5] = true; | |
defaultHighlights[1][6] = true; | |
// highlight "vor" | |
defaultHighlights[3][4] = true; | |
defaultHighlights[3][5] = true; | |
defaultHighlights[3][6] = true; | |
} else if (minute >= 50 && minute < 55) { | |
// highlight "zehn" | |
defaultHighlights[1][8] = true; | |
defaultHighlights[1][9] = true; | |
defaultHighlights[1][10] = true; | |
defaultHighlights[1][11] = true; | |
// highlight "vor" | |
defaultHighlights[3][4] = true; | |
defaultHighlights[3][5] = true; | |
defaultHighlights[3][6] = true; | |
} else if (minute >= 55) { | |
// highlight "fünf" | |
defaultHighlights[2][7] = true; | |
defaultHighlights[2][8] = true; | |
defaultHighlights[2][9] = true; | |
defaultHighlights[2][10] = true; | |
// highlight "vor" | |
defaultHighlights[3][4] = true; | |
defaultHighlights[3][5] = true; | |
defaultHighlights[3][6] = true; | |
} | |
if (hour > 12) { | |
hour = hour - 12; | |
} | |
if (hour === 1) { | |
defaultHighlights[4][8] = true; | |
defaultHighlights[4][9] = true; | |
defaultHighlights[4][10] = true; | |
if (minute >= 5) { | |
defaultHighlights[4][11] = true; | |
} | |
} else if (hour === 2) { | |
defaultHighlights[5][0] = true; | |
defaultHighlights[5][1] = true; | |
defaultHighlights[5][2] = true; | |
defaultHighlights[5][3] = true; | |
} else if (hour === 3) { | |
defaultHighlights[5][4] = true; | |
defaultHighlights[5][5] = true; | |
defaultHighlights[5][6] = true; | |
defaultHighlights[5][7] = true; | |
} else if (hour === 4) { | |
defaultHighlights[5][8] = true; | |
defaultHighlights[5][9] = true; | |
defaultHighlights[5][10] = true; | |
defaultHighlights[5][11] = true; | |
} else if (hour === 5) { | |
defaultHighlights[6][0] = true; | |
defaultHighlights[6][1] = true; | |
defaultHighlights[6][2] = true; | |
defaultHighlights[6][3] = true; | |
} else if (hour === 6) { | |
defaultHighlights[6][4] = true; | |
defaultHighlights[6][5] = true; | |
defaultHighlights[6][6] = true; | |
defaultHighlights[6][7] = true; | |
} else if (hour === 7) { | |
defaultHighlights[7][0] = true; | |
defaultHighlights[7][1] = true; | |
defaultHighlights[7][2] = true; | |
defaultHighlights[7][3] = true; | |
defaultHighlights[7][4] = true; | |
defaultHighlights[7][5] = true; | |
} else if (hour === 8) { | |
defaultHighlights[7][7] = true; | |
defaultHighlights[7][8] = true; | |
defaultHighlights[7][9] = true; | |
defaultHighlights[7][10] = true; | |
} else if (hour === 9) { | |
defaultHighlights[8][0] = true; | |
defaultHighlights[8][1] = true; | |
defaultHighlights[8][2] = true; | |
defaultHighlights[8][3] = true; | |
} else if (hour === 10) { | |
defaultHighlights[8][5] = true; | |
defaultHighlights[8][6] = true; | |
defaultHighlights[8][7] = true; | |
defaultHighlights[8][8] = true; | |
} else if (hour === 11) { | |
defaultHighlights[6][9] = true; | |
defaultHighlights[6][10] = true; | |
defaultHighlights[6][11] = true; | |
} else if (hour === 12) { | |
defaultHighlights[4][3] = true; | |
defaultHighlights[4][4] = true; | |
defaultHighlights[4][5] = true; | |
defaultHighlights[4][6] = true; | |
defaultHighlights[4][7] = true; | |
} | |
return defaultHighlights; | |
} | |
/** | |
* Sets the background on the widget. | |
* | |
* If the script/widget is running as a widget, | |
* set the background from the cache. | |
* | |
* If no background image is in the cache, | |
* default to the gray gradient. | |
* | |
* If running in the app, prompt the user to select a | |
* background image. Persist in cache. | |
*/ | |
async function setBackground(widget, { | |
useBackgroundImage, | |
backgroundColor, | |
}) { | |
if (useBackgroundImage) { | |
// Determine if our image exists and when it was saved. | |
const files = FileManager.local(); | |
const path = files.joinPath( | |
files.documentsDirectory(), | |
'word-clock-widget-background' | |
); | |
const exists = files.fileExists(path); | |
// If it exists and we're running in the widget, | |
// use photo from cache | |
// Or we're invoking the script to run FROM the widget | |
// with a widgetParameter | |
if (exists && config.runsInWidget | |
|| args.widgetParameter === 'callback') { | |
widget.backgroundImage = files.readImage(path); | |
// If it's missing when running in the widget, | |
// fallback to backgroundColor | |
} else if (!exists && config.runsInWidget) { | |
const bgColor = new LinearGradient(); | |
bgColor.colors = backgroundColor; | |
bgColor.locations = [0.0, 1.0]; | |
widget.backgroundGradient = bgColor; | |
// But if we're running in app, prompt the user for | |
// the image. | |
} else if (config.runsInApp) { | |
const img = await Photos.fromLibrary(); | |
widget.backgroundImage = img; | |
files.writeImage(path, img); | |
} | |
} else { | |
const bgColor = new LinearGradient(); | |
bgColor.colors = backgroundColor; | |
bgColor.locations = [0.0, 1.0]; | |
widget.backgroundGradient = bgColor; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment