-
Notifications
You must be signed in to change notification settings - Fork 6
/
utils.ts
133 lines (119 loc) · 3.33 KB
/
utils.ts
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import add from "date-fns/add";
import formatDistanceToNow from "date-fns/formatDistanceToNow";
import {
MediaTitle,
MediaRelation,
AnimeFragmentFragment,
MediaStatus,
Maybe,
FuzzyDate,
} from "./graphql/generated";
export function notEmpty<TValue>(
value: TValue | null | undefined
): value is TValue {
return value !== null && value !== undefined;
}
const monthMap: { [n: number]: string } = {
1: "January",
2: "February",
3: "March",
4: "April",
5: "May",
6: "June",
7: "July",
8: "August",
9: "September",
10: "October",
11: "November",
12: "December",
};
export function getTitle(
title: MediaTitle | undefined | null
): string | undefined {
if (!title) return undefined;
return title.english ?? title.romaji ?? title.native ?? undefined;
}
// for making sure TS exhaustively checks switches
export function assertUnreachable(x: never): never {
throw new Error("Didn't expect to get here");
}
export function getReadableMediaRelation(mediaRelation: MediaRelation): string {
switch (mediaRelation) {
case MediaRelation.Adaptation:
return "Adaptation";
case MediaRelation.Alternative:
return "Alternative";
case MediaRelation.Prequel:
return "Prequel";
case MediaRelation.Parent:
return "Parent";
case MediaRelation.Sequel:
return "Sequel";
case MediaRelation.Character:
return "Character";
case MediaRelation.SideStory:
return "Side story";
case MediaRelation.Summary:
return "Summary";
case MediaRelation.SpinOff:
return "Spin off";
case MediaRelation.Other:
return "Other";
case MediaRelation.Source:
return "Source";
case MediaRelation.Compilation:
return "Compilation";
case MediaRelation.Contains:
return "Contains";
}
}
export function getDateText(
date: Maybe<
{ __typename?: "FuzzyDate" } & Pick<FuzzyDate, "year" | "month" | "day">
>,
dateType?: string
): string | undefined {
if (!date) return undefined;
const _dateType = dateType ? `${dateType}: ` : "";
if (date.month && date.day && date.year) {
return `${_dateType}${date.month}/${date.day}/${date.year}`;
}
if (date.month && date.year) {
return `${_dateType}${monthMap[date.month]} ${date.year}`;
}
if (date.year) {
return `${_dateType}${date.year}`;
}
}
export function getAiringStatusText(
media: AnimeFragmentFragment,
now: Date
): string | undefined {
switch (media.status) {
case MediaStatus.Releasing:
return media.nextAiringEpisode
? `EP ${media.nextAiringEpisode?.episode} airs in ${formatDistanceToNow(
add(now, {
seconds: media.nextAiringEpisode?.timeUntilAiring ?? 0,
})
)}`
: "Releasing";
case MediaStatus.NotYetReleased:
return media.startDate
? getDateText(media.startDate, "Starting")
: "Not yet released";
case MediaStatus.Hiatus:
return "On hiatus";
case MediaStatus.Finished:
return media.endDate
? getDateText(media.endDate, "Finished")
: "Finished";
case MediaStatus.Cancelled:
return media.endDate
? getDateText(media.endDate, "Cancelled")
: "Cancelled";
}
}
export function getProgress(media: AnimeFragmentFragment, progress: number) {
return media.episodes ? `${progress}/${media.episodes} EP` : `${progress} EP`;
}