@mideind/netskrafl-react 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +8 -0
- package/.eslintrc.json +13 -0
- package/README.md +63 -0
- package/dist/cjs/index.css +6837 -0
- package/dist/cjs/index.js +3046 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/index.css +6837 -0
- package/dist/esm/index.js +3046 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/package.json +63 -0
- package/rollup.config.js +60 -0
- package/src/components/index.ts +2 -0
- package/src/components/netskrafl/Netskrafl.stories.tsx +66 -0
- package/src/components/netskrafl/Netskrafl.tsx +135 -0
- package/src/components/netskrafl/Netskrafl.types.ts +7 -0
- package/src/components/netskrafl/index.ts +2 -0
- package/src/css/fonts.css +4 -0
- package/src/css/glyphs.css +224 -0
- package/src/css/skrafl-explo.css +6616 -0
- package/src/fonts/glyphicons-regular.eot +0 -0
- package/src/fonts/glyphicons-regular.ttf +0 -0
- package/src/fonts/glyphicons-regular.woff +0 -0
- package/src/index.ts +2 -0
- package/src/messages/messages.json +1576 -0
- package/src/mithril/actions.ts +319 -0
- package/src/mithril/bag.ts +65 -0
- package/src/mithril/bestdisplay.ts +74 -0
- package/src/mithril/blankdialog.ts +94 -0
- package/src/mithril/board.ts +336 -0
- package/src/mithril/buttons.ts +303 -0
- package/src/mithril/challengedialog.ts +186 -0
- package/src/mithril/channel.ts +162 -0
- package/src/mithril/chat.ts +228 -0
- package/src/mithril/components.ts +496 -0
- package/src/mithril/dragdrop.ts +219 -0
- package/src/mithril/elopage.ts +180 -0
- package/src/mithril/friend.ts +227 -0
- package/src/mithril/game.ts +1378 -0
- package/src/mithril/gameview.ts +111 -0
- package/src/mithril/globalstate.ts +33 -0
- package/src/mithril/i18n.ts +186 -0
- package/src/mithril/localstorage.ts +133 -0
- package/src/mithril/login.ts +122 -0
- package/src/mithril/logo.ts +270 -0
- package/src/mithril/main.ts +737 -0
- package/src/mithril/mithril.ts +29 -0
- package/src/mithril/model.ts +817 -0
- package/src/mithril/movelistitem.ts +226 -0
- package/src/mithril/page.ts +852 -0
- package/src/mithril/playername.ts +91 -0
- package/src/mithril/promodialog.ts +82 -0
- package/src/mithril/recentlist.ts +148 -0
- package/src/mithril/request.ts +52 -0
- package/src/mithril/review.ts +634 -0
- package/src/mithril/rightcolumn.ts +398 -0
- package/src/mithril/searchbutton.ts +118 -0
- package/src/mithril/statsdisplay.ts +109 -0
- package/src/mithril/tabs.ts +169 -0
- package/src/mithril/tile.ts +145 -0
- package/src/mithril/twoletter.ts +76 -0
- package/src/mithril/types.ts +379 -0
- package/src/mithril/userinfodialog.ts +171 -0
- package/src/mithril/util.ts +304 -0
- package/src/mithril/wait.ts +246 -0
- package/src/mithril/wordcheck.ts +102 -0
- package/tsconfig.json +28 -0
- package/vite.config.ts +12 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
EloPage.ts
|
|
4
|
+
|
|
5
|
+
Elo status list component
|
|
6
|
+
|
|
7
|
+
Copyright (C) 2024 Miðeind ehf.
|
|
8
|
+
Author: Vilhjalmur Thorsteinsson
|
|
9
|
+
|
|
10
|
+
The Creative Commons Attribution-NonCommercial 4.0
|
|
11
|
+
International Public License (CC-BY-NC 4.0) applies to this software.
|
|
12
|
+
For further information, see https://github.com/mideind/Netskrafl
|
|
13
|
+
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { IView, UserListItem } from "./types";
|
|
17
|
+
import { ComponentFunc, VnodeChildren, m } from "./mithril";
|
|
18
|
+
import { ts, mt } from "./i18n";
|
|
19
|
+
import { glyph, glyphGrayed, nbsp } from "./util";
|
|
20
|
+
import { ChallengeButton, UserInfoButton } from "./components";
|
|
21
|
+
|
|
22
|
+
type EloListSelection = "human" | "all" | "manual";
|
|
23
|
+
|
|
24
|
+
interface IAttributes {
|
|
25
|
+
view: IView;
|
|
26
|
+
id: string;
|
|
27
|
+
key: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const EloPage: ComponentFunc<IAttributes> = () => {
|
|
31
|
+
|
|
32
|
+
// Show the header of an Elo ranking list and then the list itself
|
|
33
|
+
|
|
34
|
+
let sel: EloListSelection = "human"; // Default: show ranking for human games only
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
view: (vnode) => {
|
|
38
|
+
return m.fragment({}, [
|
|
39
|
+
m(".listitem.listheader", { key: "header" },
|
|
40
|
+
[
|
|
41
|
+
m("span.list-ch", glyphGrayed("hand-right", { title: ts('Skora á') })),
|
|
42
|
+
mt("span.list-rank", "Röð"),
|
|
43
|
+
m("span.list-rank-no-mobile", { title: ts('Röð í gær') }, ts("1d")),
|
|
44
|
+
m("span.list-rank-no-mobile", { title: ts('Röð fyrir viku') }, ts("7d")),
|
|
45
|
+
mt("span.list-nick-elo", "Einkenni"),
|
|
46
|
+
m("span.list-elo", { title: ts('Elo-stig') }, ts("Elo")),
|
|
47
|
+
m("span.list-elo-no-mobile", { title: ts('Elo-stig í gær') }, ts("1d")),
|
|
48
|
+
m("span.list-elo-no-mobile", { title: ts('Elo-stig fyrir viku') }, ts("7d")),
|
|
49
|
+
m("span.list-elo-no-mobile", { title: ts('Elo-stig fyrir mánuði') }, ts("30d")),
|
|
50
|
+
m("span.list-games", { title: ts('Fjöldi viðureigna') }, glyph("th")),
|
|
51
|
+
m("span.list-ratio", { title: ts('Vinningshlutfall') }, glyph("bookmark")),
|
|
52
|
+
m("span.list-avgpts", { title: ts('Meðalstigafjöldi') }, glyph("dashboard")),
|
|
53
|
+
mt("span.list-info-hdr", "Ferill"),
|
|
54
|
+
// m("span.list-newbag", glyphGrayed("shopping-bag", { title: ts('Gamli pokinn') })),
|
|
55
|
+
m(".toggler[id='elo-toggler']", { title: ts("elo_list_choice") },
|
|
56
|
+
[
|
|
57
|
+
m(".option.x-small",
|
|
58
|
+
{
|
|
59
|
+
// Show ranking for human games only
|
|
60
|
+
className: (sel === "human" ? "selected" : ""),
|
|
61
|
+
onclick: (ev: Event) => { sel = "human"; ev.preventDefault(); },
|
|
62
|
+
},
|
|
63
|
+
glyph("user")
|
|
64
|
+
),
|
|
65
|
+
m(".option.x-small",
|
|
66
|
+
{
|
|
67
|
+
// Show ranking for all games, including robots
|
|
68
|
+
className: (sel === "all" ? "selected" : ""),
|
|
69
|
+
onclick: (ev: Event) => { sel = "all"; ev.preventDefault(); },
|
|
70
|
+
},
|
|
71
|
+
glyph("cog")
|
|
72
|
+
),
|
|
73
|
+
m(".option.x-small",
|
|
74
|
+
{
|
|
75
|
+
// Show ranking for manual games only
|
|
76
|
+
className: (sel === "manual" ? "selected" : ""),
|
|
77
|
+
onclick: (ev: Event) => { sel = "manual"; ev.preventDefault(); },
|
|
78
|
+
},
|
|
79
|
+
glyph("lightbulb")
|
|
80
|
+
)
|
|
81
|
+
]
|
|
82
|
+
)
|
|
83
|
+
]
|
|
84
|
+
),
|
|
85
|
+
m(EloList,
|
|
86
|
+
{
|
|
87
|
+
id: vnode.attrs.id,
|
|
88
|
+
sel: sel,
|
|
89
|
+
view: vnode.attrs.view,
|
|
90
|
+
key: sel,
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
]);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const EloList: ComponentFunc<{
|
|
100
|
+
view: IView;
|
|
101
|
+
id: string;
|
|
102
|
+
sel: EloListSelection;
|
|
103
|
+
}> = (initialVnode) => {
|
|
104
|
+
|
|
105
|
+
const outerView = initialVnode.attrs.view;
|
|
106
|
+
const model = outerView.model;
|
|
107
|
+
const state = model.state;
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
|
|
111
|
+
view: (vnode) => {
|
|
112
|
+
|
|
113
|
+
function itemize(item: UserListItem, i: number) {
|
|
114
|
+
|
|
115
|
+
// Generate a list item about a user in an Elo ranking table
|
|
116
|
+
|
|
117
|
+
const isRobot = item.userid.indexOf("robot-") === 0;
|
|
118
|
+
|
|
119
|
+
function rankStr(rank: number, ref?: number): string {
|
|
120
|
+
// Return a rank string or dash if no rank or not meaningful
|
|
121
|
+
// (i.e. if the reference, such as the number of games, is zero)
|
|
122
|
+
if (rank === 0 || (ref !== undefined && ref === 0))
|
|
123
|
+
return "--";
|
|
124
|
+
return rank.toString();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let nick: VnodeChildren = item.nick;
|
|
128
|
+
let ch = m("span.list-ch", nbsp());
|
|
129
|
+
const userId = state?.userId ?? "";
|
|
130
|
+
if (item.userid != userId && !item.inactive) {
|
|
131
|
+
ch = m(ChallengeButton, { view: outerView, item });
|
|
132
|
+
}
|
|
133
|
+
if (isRobot) {
|
|
134
|
+
nick = m("span", [glyph("cog"), nbsp(), nick]);
|
|
135
|
+
}
|
|
136
|
+
if (item.fairplay && !isRobot)
|
|
137
|
+
nick = m("span",
|
|
138
|
+
[m("span.fairplay-btn", { title: ts("Skraflar án hjálpartækja") }), nick]);
|
|
139
|
+
|
|
140
|
+
return m(".listitem",
|
|
141
|
+
{
|
|
142
|
+
key: vnode.attrs.sel + i,
|
|
143
|
+
className: (i % 2 === 0 ? "oddlist" : "evenlist")
|
|
144
|
+
},
|
|
145
|
+
[
|
|
146
|
+
ch, // Challenge icon (right-hand)
|
|
147
|
+
m("span.list-rank.bold", rankStr(item.rank)),
|
|
148
|
+
m("span.list-rank-no-mobile", rankStr(item.rank_yesterday)),
|
|
149
|
+
m("span.list-rank-no-mobile", rankStr(item.rank_week_ago)),
|
|
150
|
+
m("span.list-nick-elo", { title: item.fullname }, nick),
|
|
151
|
+
m("span.list-elo.bold", item.elo),
|
|
152
|
+
m("span.list-elo-no-mobile", rankStr(item.elo_yesterday, item.games_yesterday)),
|
|
153
|
+
m("span.list-elo-no-mobile", rankStr(item.elo_week_ago, item.games_week_ago)),
|
|
154
|
+
m("span.list-elo-no-mobile", rankStr(item.elo_month_ago, item.games_month_ago)),
|
|
155
|
+
m("span.list-games.bold", item.games >= 100000 ? Math.round(item.games / 1000) + "K" : item.games),
|
|
156
|
+
m("span.list-ratio", item.ratio + "%"),
|
|
157
|
+
m("span.list-avgpts", item.avgpts),
|
|
158
|
+
item.userid === userId ? nbsp() : m(UserInfoButton, { view: outerView, item }),
|
|
159
|
+
]
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let list: UserListItem[] = [];
|
|
164
|
+
if (model.userList === undefined) {
|
|
165
|
+
// Loading in progress
|
|
166
|
+
// pass
|
|
167
|
+
}
|
|
168
|
+
else if (model.userList === null || model.userListCriteria?.query !== "elo" ||
|
|
169
|
+
model.userListCriteria.spec !== vnode.attrs.sel.toString()) {
|
|
170
|
+
// We're not showing the correct list: request a new one
|
|
171
|
+
model.loadUserList({ query: "elo", spec: vnode.attrs.sel }, true);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
list = model.userList;
|
|
175
|
+
}
|
|
176
|
+
return m("div", { id: vnode.attrs.id }, list.map(itemize));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
};
|
|
180
|
+
};
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Friend.ts
|
|
4
|
+
|
|
5
|
+
Code for dialog components used in management of friends
|
|
6
|
+
|
|
7
|
+
Copyright (C) 2023 Miðeind ehf.
|
|
8
|
+
Original author: Vilhjálmur Þorsteinsson
|
|
9
|
+
|
|
10
|
+
The Creative Commons Attribution-NonCommercial 4.0
|
|
11
|
+
International Public License (CC-BY-NC 4.0) applies to this software.
|
|
12
|
+
For further information, see https://github.com/mideind/Netskrafl
|
|
13
|
+
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
FriendPromoteDialog, FriendThanksDialog,
|
|
18
|
+
FriendCancelDialog, FriendCancelConfirmDialog
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
import { m, ComponentFunc, VnodeDOM } from "./mithril";
|
|
22
|
+
import { IView } from "./types";
|
|
23
|
+
import { DialogButton } from "./components";
|
|
24
|
+
import { glyph, nbsp, buttonOver, buttonOut, registerSalesCloud } from "./util";
|
|
25
|
+
|
|
26
|
+
const FriendPromoteDialog: ComponentFunc<{
|
|
27
|
+
view: IView;
|
|
28
|
+
}> = (initialVnode) => {
|
|
29
|
+
|
|
30
|
+
// A dialog that offers friendship to the user
|
|
31
|
+
|
|
32
|
+
const attrs = initialVnode.attrs;
|
|
33
|
+
const view = attrs.view;
|
|
34
|
+
const model = view.model;
|
|
35
|
+
|
|
36
|
+
// Load the friendHTML if not already loaded
|
|
37
|
+
model.loadFriendPromo();
|
|
38
|
+
|
|
39
|
+
function onUpdate(vnode: VnodeDOM) {
|
|
40
|
+
if (!vnode || !vnode.dom)
|
|
41
|
+
return;
|
|
42
|
+
const noButtons = vnode.dom.getElementsByClassName("btn-promo-no") as HTMLCollectionOf<HTMLElement>;
|
|
43
|
+
if (noButtons) {
|
|
44
|
+
// Override onclick, onmouseover and onmouseout for No buttons
|
|
45
|
+
for (let btn of noButtons) {
|
|
46
|
+
btn.onclick = (ev: MouseEvent) => { view.popDialog(); ev.preventDefault(); };
|
|
47
|
+
btn.onmouseover = buttonOver;
|
|
48
|
+
btn.onmouseout = buttonOut;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Override onmouseover and onmouseout for Yes buttons
|
|
52
|
+
const yesButtons = vnode.dom.getElementsByClassName("btn-promo-yes") as HTMLCollectionOf<HTMLElement>;
|
|
53
|
+
if (yesButtons) {
|
|
54
|
+
for (let btn of yesButtons) {
|
|
55
|
+
btn.onmouseover = buttonOver;
|
|
56
|
+
btn.onmouseout = buttonOut;
|
|
57
|
+
}
|
|
58
|
+
// We have a 'yes' button: register SalesCloud to handle it
|
|
59
|
+
registerSalesCloud();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
view: () => {
|
|
65
|
+
return m(".modal-dialog",
|
|
66
|
+
{ id: "promo-dialog", style: { visibility: "visible" } },
|
|
67
|
+
m(".ui-widget.ui-widget-content.ui-corner-all", { id: "promo-form" },
|
|
68
|
+
m(".promo-content",
|
|
69
|
+
{
|
|
70
|
+
oncreate: (vnode) => onUpdate(vnode),
|
|
71
|
+
onupdate: (vnode) => onUpdate(vnode)
|
|
72
|
+
},
|
|
73
|
+
m.trust(model.friendHTML || "<p>Sæki texta...</p>")
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const FriendThanksDialog: ComponentFunc<{
|
|
82
|
+
view: IView;
|
|
83
|
+
}> = (initialVnode) => {
|
|
84
|
+
|
|
85
|
+
// A dialog that offers friendship to the user
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
view: () => {
|
|
89
|
+
return m(".modal-dialog",
|
|
90
|
+
{ id: "thanks-dialog", style: { visibility: "visible" } },
|
|
91
|
+
m(".ui-widget.ui-widget-content.ui-corner-all", { id: "thanks-form" },
|
|
92
|
+
[
|
|
93
|
+
m(".thanks-content", [
|
|
94
|
+
m("h3", "Frábært!"),
|
|
95
|
+
m("p", [
|
|
96
|
+
"Bestu þakkir fyrir að gerast ", glyph("coffee-cup"), nbsp(), m("b", "Vinur Netskrafls"), "."
|
|
97
|
+
]),
|
|
98
|
+
m("p", [
|
|
99
|
+
"Fríðindi þín virkjast um leið og greiðsla hefur verið staðfest. ",
|
|
100
|
+
m("b", "Það getur tekið nokkrar mínútur."),
|
|
101
|
+
" Þú færð staðfestingu og kvittun í tölvupósti."
|
|
102
|
+
]),
|
|
103
|
+
]),
|
|
104
|
+
m(DialogButton,
|
|
105
|
+
{
|
|
106
|
+
id: "btn-thanks",
|
|
107
|
+
title: "Áfram",
|
|
108
|
+
onclick: (ev: Event) => {
|
|
109
|
+
// Go back to the main page
|
|
110
|
+
// The dialog is popped automatically upon the route change
|
|
111
|
+
m.route.set("/main");
|
|
112
|
+
ev.preventDefault();
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
glyph("ok")
|
|
116
|
+
)
|
|
117
|
+
]
|
|
118
|
+
)
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const FriendCancelDialog: ComponentFunc<{
|
|
125
|
+
view: IView;
|
|
126
|
+
}> = (initialVnode) => {
|
|
127
|
+
|
|
128
|
+
// A dialog that offers friendship to the user
|
|
129
|
+
|
|
130
|
+
const attrs = initialVnode.attrs;
|
|
131
|
+
const view = attrs.view;
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
view: () => {
|
|
135
|
+
return m(".modal-dialog",
|
|
136
|
+
{ id: "cancel-dialog", style: { visibility: "visible" } },
|
|
137
|
+
m(".ui-widget.ui-widget-content.ui-corner-all", { id: "cancel-form" }, [
|
|
138
|
+
m("div", { id: "cancel-content" }, [
|
|
139
|
+
m("h3", "Hætta sem vinur Netskrafls?"),
|
|
140
|
+
m("p", [
|
|
141
|
+
"Viltu hætta sem ", glyph("coffee-cup"), nbsp(), m("b", "vinur Netskrafls"),
|
|
142
|
+
" og missa þar með þau fríðindi sem því tengjast?"
|
|
143
|
+
]),
|
|
144
|
+
m("p", "Fríðindin eru:"),
|
|
145
|
+
m("ul", [
|
|
146
|
+
m("li", [
|
|
147
|
+
m("b", "Ótakmarkaður fjöldi viðureigna"), " í gangi samtímis", m("br"),
|
|
148
|
+
"(í stað 8 að hámarki)"
|
|
149
|
+
]),
|
|
150
|
+
m("li", [
|
|
151
|
+
"Aðgangur að ", m("b", "yfirliti"), " í lok viðureignar"
|
|
152
|
+
]),
|
|
153
|
+
m("li", [
|
|
154
|
+
m("b", "Keppnishamur"), " án \"græna þumalsins\""
|
|
155
|
+
]),
|
|
156
|
+
]),
|
|
157
|
+
m(DialogButton,
|
|
158
|
+
{
|
|
159
|
+
id: "btn-cancel-no",
|
|
160
|
+
title: "Nei",
|
|
161
|
+
onclick: (ev: Event) => {
|
|
162
|
+
ev.preventDefault();
|
|
163
|
+
view.popDialog();
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
[ glyph("remove"), " Nei" ]
|
|
167
|
+
),
|
|
168
|
+
m(DialogButton,
|
|
169
|
+
{
|
|
170
|
+
id: "btn-cancel-yes",
|
|
171
|
+
title: "Já",
|
|
172
|
+
onclick: (ev: Event) => {
|
|
173
|
+
ev.preventDefault();
|
|
174
|
+
view.popDialog();
|
|
175
|
+
// Initiate cancellation of the friendship
|
|
176
|
+
view.cancelFriendship();
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
[ glyph("ok"), " Já, vil hætta" ]
|
|
180
|
+
)
|
|
181
|
+
]),
|
|
182
|
+
])
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const FriendCancelConfirmDialog: ComponentFunc<{
|
|
189
|
+
view: IView;
|
|
190
|
+
}> = (initialVnode) => {
|
|
191
|
+
|
|
192
|
+
// A dialog that confirms cancellation of friendship
|
|
193
|
+
|
|
194
|
+
const attrs = initialVnode.attrs;
|
|
195
|
+
const view = attrs.view;
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
view: () => {
|
|
199
|
+
return m(".modal-dialog",
|
|
200
|
+
{ id: "confirm-dialog", style: { visibility: "visible" } },
|
|
201
|
+
m(".ui-widget.ui-widget-content.ui-corner-all", { id: "confirm-form" },
|
|
202
|
+
[
|
|
203
|
+
m(".confirm-content", [
|
|
204
|
+
m("h3", "Staðfesting"),
|
|
205
|
+
m("p", [
|
|
206
|
+
"Þú ert ekki lengur skráð(ur) sem ",
|
|
207
|
+
glyph("coffee-cup"), nbsp(), m("b", "vinur Netskrafls"), "."
|
|
208
|
+
]),
|
|
209
|
+
]),
|
|
210
|
+
m(DialogButton,
|
|
211
|
+
{
|
|
212
|
+
id: "btn-thanks",
|
|
213
|
+
title: "Áfram",
|
|
214
|
+
onclick: (ev: Event) => {
|
|
215
|
+
ev.preventDefault();
|
|
216
|
+
view.popDialog();
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
glyph("ok")
|
|
220
|
+
)
|
|
221
|
+
]
|
|
222
|
+
)
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|