Repository navigation
Expand file tree
/
Copy pathformat.js
More file actions
98 lines (91 loc) · 3.28 KB
/
Copy pathformat.js
File metadata and controls
98 lines (91 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* Pure helpers shared by the module (browser) and its tests (Node). */
(function (root, factory) {
var api = factory();
if (typeof module === "object" && module.exports) module.exports = api;
// Also on the page when `module` exists there too: older mirrors run Electron
// with Node integration on, so the browser sees `module` as well.
if (root) root.ChoresMachineFormat = api;
})(typeof self !== "undefined" ? self : this, function () {
/**
* Every word the module shows, in English. `translations/*.json` has the
* same keys per language, and the `strings` config option overrides any
* of them. `{n}` is filled in with a number.
*/
var STRINGS = {
dueToday: "Due today",
dueYesterday: "Due yesterday",
dueDaysAgo: "Due {n} days ago",
tomorrow: "Tomorrow",
inDays: "In {n} days",
more: "+ {n} more",
allClear: "All clear",
loading: "Loading…",
noToken: "Add your Chores Machine token to the module config.",
unknownLink: "The Chores Machine link is unknown or was removed. Make a new one in the app: You → API access.",
needsPro: "The Chores Machine feed needs Pro on the account that made the link.",
tooMany: "Too many requests. Raise updateInterval.",
unreachable: "Chores Machine could not be reached."
};
function fill(template, n) {
return String(template).replace("{n}", n);
}
/**
* Gentle due text, the same words as the app (ChoreModel.dueLabel).
* `dueInDays` comes from the API, already in the list's own timezone.
*/
function dueLabel(days, strings) {
var s = strings || STRINGS;
if (days < -1) return fill(s.dueDaysAgo, -days);
if (days === -1) return s.dueYesterday;
if (days === 0) return s.dueToday;
if (days === 1) return s.tomorrow;
return fill(s.inDays, days);
}
/** Who a chore is for: whose turn it is, else its owners, else nobody (anyone). */
function whoFor(chore) {
if (chore.turn) return chore.turn.name;
if (chore.owners && chore.owners.length) {
return chore.owners.map(function (o) { return o.name; }).join(", ");
}
return "";
}
/**
* Add-ons that come along with the chore's next completion ("change the
* bag" every 4th refill). The rest stay out of sight until their turn.
* Older feeds have no `addons`, so none.
*/
function dueAddons(chore) {
return (chore && chore.addons ? chore.addons : []).filter(function (a) { return a.isDue; });
}
/** The API's error body, in words someone at a mirror can act on. */
function errorText(status, body, strings) {
var s = strings || STRINGS;
if (status === 401) return s.unknownLink;
if (status === 403) return s.needsPro;
if (status === 429) return s.tooMany;
if (status === 0) return s.unreachable;
return (body && body.message) || s.unreachable;
}
/** Lists to show, in order, with each list's chores capped. */
function lists(feed, maxPerList) {
return (feed && feed.groups ? feed.groups : []).map(function (group) {
var chores = group.chores || [];
return {
id: group.id,
title: group.title,
chores: maxPerList ? chores.slice(0, maxPerList) : chores,
more: maxPerList && chores.length > maxPerList ? chores.length - maxPerList : 0,
nextUp: group.nextUp || null
};
});
}
return {
STRINGS: STRINGS,
fill: fill,
dueLabel: dueLabel,
whoFor: whoFor,
dueAddons: dueAddons,
errorText: errorText,
lists: lists
};
});