Skip to content

Commit cca72fd

Browse files
committedMay 18, 2021
Add a grace degradation in an offline state, link to xkcd, not the img
- handle a case when the device is offline -- instead of an error across the widget, there's a friendly "You're offline" message, - when pressing the widget, open the xkcd page rather than the image alone.
1 parent b8d63d2 commit cca72fd

File tree

1 file changed

+46
-21
lines changed

1 file changed

+46
-21
lines changed
 

‎src/Random xkcd Widget.js

+46-21
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
* Displays a random xkcd comic in a widget.
1010
*
11-
* It's a modified version of
11+
* It's a <em>heavily</em> modified version of
1212
* <a href="https://gist.github.com/rudotriton/9d11ce1101ff1269f56844871b3fd536">rudotriton's script</a>.
1313
*/
1414

@@ -17,22 +17,36 @@ const URL_PREFIX = 'https://xkcd.com/';
1717
const URL_POSTFIX = 'info.0.json';
1818
// For development, displays the widget if run from the Scriptable app.
1919
const DEBUG = false;
20+
const IS_ONLINE = await checkIsOnline();
2021

21-
const [image, title, imageURL] = await getRandomComic();
22+
const comic = IS_ONLINE ? await getRandomComic() : undefined;
2223

2324
if (config.runsInWidget) {
2425
// Create and show the widget on home screen.
25-
const widget = createWidget(image, title, imageURL);
26+
const widget = createWidget(comic);
2627
Script.setWidget(widget);
2728
Script.complete();
2829
} else if (DEBUG) {
29-
const widget = createWidget(image, title, imageURL);
30+
const widget = createWidget(comic);
3031
await widget.presentLarge();
3132
} else {
32-
Safari.open(imageURL);
33+
if (IS_ONLINE && comic?.xkcdURL) {
34+
Safari.open(comic.xkcdURL);
35+
}
3336
}
3437

35-
/** @return {Array<Image, string, string>} Random comic data. */
38+
/** @return {bool} Whether the device has internet access. */
39+
async function checkIsOnline() {
40+
const request = new Request('https://duckduckgo.com');
41+
try {
42+
await request.load();
43+
} catch (exception) {
44+
return false;
45+
}
46+
return true;
47+
}
48+
49+
/** @return {object} Data of the randomised comic. */
3650
async function getRandomComic() {
3751
const randomComicNumber = await getRandomComicNumber();
3852
const randomComicURL = URL_PREFIX + randomComicNumber + '/' + URL_POSTFIX;
@@ -42,7 +56,12 @@ async function getRandomComic() {
4256
const imageRequest = await new Request(imageURL);
4357
const image = await imageRequest.loadImage();
4458

45-
return [image, title, imageURL];
59+
return {
60+
image,
61+
title,
62+
imageURL,
63+
xkcdURL: URL_PREFIX + randomComicNumber,
64+
};
4665
}
4766

4867
/** @return {number} Random comic number. */
@@ -64,31 +83,37 @@ function getRandomNumber(min, max) {
6483
}
6584

6685
/**
67-
* @param {Image} image The image to display.
68-
* @param {string} title Title of the widget.
69-
* @param {string} widgetURL URL for the widget to open.
86+
* Creates a {@link ListWidget} displaying the given comic. If the device is offline, creates an
87+
* empty "You're offline" widget.
88+
* <p>
89+
* NOTE: The layout uses two horizontal stacks to be able to centre the title and the image. For
90+
* some reason, `WidgetText#centerAlignText()` didn't work on home screen.
91+
* @param {object} comic Data of a randomised comic.
7092
* @return {ListWidget} The newly created widget instance.
7193
*/
72-
function createWidget(image, title, widgetURL) {
94+
function createWidget(comic) {
7395
const widget = new ListWidget();
74-
widget.url = widgetURL;
75-
widget.refreshAfterDate = getDateIn30Minutes();
7696

77-
// The layout uses two horizontal stacks to be able to centre the title and the image. For some
78-
// reason, `WidgetTexts#centerAlignText()` didn't work on home screen.
7997
/** @type {WidgetStack} */
8098
const titleStack = widget.addStack();
8199
titleStack.addSpacer(null);
82100
/** @type {WidgetText} */
83-
const titleStackText = titleStack.addText(title);
101+
const titleStackText = titleStack.addText(
102+
IS_ONLINE && comic?.title ? comic.title : "You're offline"
103+
);
84104
titleStackText.font = Font.headline();
85105
titleStack.addSpacer(null);
86106

87-
/** @type {WidgetStack} */
88-
const imageStack = widget.addStack();
89-
imageStack.addSpacer(null);
90-
imageStack.addImage(image);
91-
imageStack.addSpacer(null);
107+
if (IS_ONLINE && comic) {
108+
/** @type {WidgetStack} */
109+
const imageStack = widget.addStack();
110+
imageStack.addSpacer(null);
111+
imageStack.addImage(comic.image);
112+
imageStack.addSpacer(null);
113+
114+
widget.url = comic.xkcdURL;
115+
widget.refreshAfterDate = getDateIn30Minutes();
116+
}
92117

93118
return widget;
94119
}

0 commit comments

Comments
 (0)
Please sign in to comment.