@mideind/netskrafl-react 1.0.0-beta.6 → 1.0.0-beta.7

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.
Files changed (67) hide show
  1. package/dist/cjs/css/netskrafl.css +859 -177
  2. package/dist/cjs/index.js +206 -299
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/esm/css/netskrafl.css +859 -177
  5. package/dist/esm/index.js +205 -298
  6. package/dist/esm/index.js.map +1 -1
  7. package/package.json +13 -2
  8. package/.eslintignore +0 -8
  9. package/.eslintrc.json +0 -13
  10. package/rollup.config.js +0 -67
  11. package/src/components/index.ts +0 -2
  12. package/src/components/netskrafl/Netskrafl.stories.tsx +0 -66
  13. package/src/components/netskrafl/Netskrafl.tsx +0 -155
  14. package/src/components/netskrafl/Netskrafl.types.ts +0 -7
  15. package/src/components/netskrafl/index.ts +0 -2
  16. package/src/css/fonts.css +0 -4
  17. package/src/css/glyphs.css +0 -223
  18. package/src/css/main.css +0 -4
  19. package/src/css/skrafl-explo.css +0 -6636
  20. package/src/fonts/glyphicons-regular.eot +0 -0
  21. package/src/fonts/glyphicons-regular.ttf +0 -0
  22. package/src/fonts/glyphicons-regular.woff +0 -0
  23. package/src/index.ts +0 -4
  24. package/src/messages/messages.json +0 -1576
  25. package/src/mithril/actions.ts +0 -319
  26. package/src/mithril/bag.ts +0 -65
  27. package/src/mithril/bestdisplay.ts +0 -74
  28. package/src/mithril/blankdialog.ts +0 -94
  29. package/src/mithril/board.ts +0 -339
  30. package/src/mithril/buttons.ts +0 -303
  31. package/src/mithril/challengedialog.ts +0 -186
  32. package/src/mithril/channel.ts +0 -162
  33. package/src/mithril/chat.ts +0 -228
  34. package/src/mithril/components.ts +0 -496
  35. package/src/mithril/dragdrop.ts +0 -219
  36. package/src/mithril/elopage.ts +0 -202
  37. package/src/mithril/friend.ts +0 -227
  38. package/src/mithril/game.ts +0 -1378
  39. package/src/mithril/gameview.ts +0 -111
  40. package/src/mithril/globalstate.ts +0 -33
  41. package/src/mithril/i18n.ts +0 -187
  42. package/src/mithril/localstorage.ts +0 -133
  43. package/src/mithril/login.ts +0 -122
  44. package/src/mithril/logo.ts +0 -323
  45. package/src/mithril/main.ts +0 -755
  46. package/src/mithril/mithril.ts +0 -29
  47. package/src/mithril/model.ts +0 -855
  48. package/src/mithril/movelistitem.ts +0 -226
  49. package/src/mithril/page.ts +0 -856
  50. package/src/mithril/playername.ts +0 -91
  51. package/src/mithril/promodialog.ts +0 -82
  52. package/src/mithril/recentlist.ts +0 -148
  53. package/src/mithril/request.ts +0 -52
  54. package/src/mithril/review.ts +0 -634
  55. package/src/mithril/rightcolumn.ts +0 -398
  56. package/src/mithril/searchbutton.ts +0 -118
  57. package/src/mithril/statsdisplay.ts +0 -109
  58. package/src/mithril/tabs.ts +0 -169
  59. package/src/mithril/tile.ts +0 -145
  60. package/src/mithril/twoletter.ts +0 -76
  61. package/src/mithril/types.ts +0 -384
  62. package/src/mithril/userinfodialog.ts +0 -171
  63. package/src/mithril/util.ts +0 -304
  64. package/src/mithril/wait.ts +0 -246
  65. package/src/mithril/wordcheck.ts +0 -102
  66. package/tsconfig.json +0 -28
  67. package/vite.config.ts +0 -12
@@ -1,169 +0,0 @@
1
- /*
2
- Tabs.ts
3
-
4
- Utility functions to set up tabbed views
5
-
6
- Copyright (C) 2024 Miðeind ehf.
7
- Author: Vilhjalmur Thorsteinsson
8
-
9
- The Creative Commons Attribution-NonCommercial 4.0
10
- International Public License (CC-BY-NC 4.0) applies to this software.
11
- For further information, see https://github.com/mideind/Netskrafl
12
-
13
- */
14
-
15
- import { IView } from "./types";
16
- import { m } from "./mithril";
17
- import { getUrlVars } from "./util";
18
-
19
- const ROUTE_PREFIX = "/page#!";
20
- const ROUTE_PREFIX_LEN = ROUTE_PREFIX.length;
21
-
22
- export type TabVnode = m.VnodeDOM<
23
- Record<string, any>,
24
- {
25
- selected: number;
26
- lis: HTMLElement[];
27
- ids: string[];
28
- }
29
- >;
30
-
31
- export function makeTabs(view: IView, id: string, createFunc: ((vnode: TabVnode) => void) | undefined, wireHrefs: boolean, vnode: TabVnode) {
32
- // When the tabs are displayed for the first time, wire'em up
33
- let tabdiv = document.getElementById(id);
34
- if (!tabdiv)
35
- return;
36
- // Add bunch of jQueryUI compatible classes
37
- tabdiv.setAttribute("class", "ui-tabs ui-widget ui-widget-content ui-corner-all");
38
- const tabul = document.querySelector("#" + id + " > ul");
39
- if (tabul) {
40
- tabul.setAttribute("class", "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");
41
- tabul.setAttribute("role", "tablist");
42
- }
43
- let tablist = document.querySelectorAll("#" + id + " > ul > li > a") as NodeListOf<HTMLElement>;
44
- let tabitems = document.querySelectorAll("#" + id + " > ul > li") as NodeListOf<HTMLElement>;
45
- let ids: string[] = [];
46
- let lis: HTMLElement[] = []; // The <li> elements
47
- // Iterate over the <a> elements inside the <li> elements inside the <ul>
48
- for (let i = 0; i < tablist.length; i++) {
49
- const href = tablist[i].getAttribute("href");
50
- if (!href) continue;
51
- ids.push(href.slice(1));
52
- // Decorate the <a> elements
53
- tablist[i].onclick = (ev) => { selectTab(vnode, i); ev.preventDefault(); };
54
- tablist[i].removeAttribute("href");
55
- tablist[i].setAttribute("class", "ui-tabs-anchor sp"); // Single-page marker
56
- tablist[i].setAttribute("role", "presentation");
57
- // Also decorate the <li> elements
58
- lis.push(tabitems[i]);
59
- tabitems[i].setAttribute("class", "ui-state-default ui-corner-top");
60
- tabitems[i].setAttribute("role", "tab");
61
- tabitems[i].onmouseover = (ev) => {
62
- (ev.currentTarget as HTMLElement).classList.toggle("ui-state-hover", true);
63
- };
64
- tabitems[i].onmouseout = (ev) => {
65
- (ev.currentTarget as HTMLElement).classList.toggle("ui-state-hover", false);
66
- };
67
- // Find the tab's content <div>
68
- const tabcontent = document.getElementById(ids[i]);
69
- // Decorate it
70
- if (tabcontent) {
71
- tabcontent.setAttribute("class", "ui-tabs-panel ui-widget-content ui-corner-bottom");
72
- tabcontent.setAttribute("role", "tabpanel");
73
- }
74
- }
75
- // Save the list of tab identifiers
76
- vnode.state.ids = ids;
77
- // Save the list of <li> elements
78
- vnode.state.lis = lis;
79
- // Select the first tab by default
80
- vnode.state.selected = 0;
81
- if (wireHrefs) {
82
- // Wire all hrefs that point to single-page URLs
83
- const model = view.model;
84
- const clickURL = (ev: Event, href: string) => {
85
- let uri = href.slice(ROUTE_PREFIX_LEN); // Cut the /page#!/ prefix off the route
86
- let qix = uri.indexOf("?");
87
- let route = (qix >= 0) ? uri.slice(0, qix) : uri;
88
- let qparams = uri.slice(route.length + 1);
89
- let params = qparams.length ? getUrlVars(qparams) : {};
90
- m.route.set(route, params);
91
- if (window.history)
92
- window.history.pushState({}, "", href); // Enable the back button
93
- ev.preventDefault();
94
- };
95
- const clickUserPrefs = (ev: Event) => {
96
- if (model?.state?.userId)
97
- // Don't show the userprefs if no user logged in
98
- view.pushDialog("userprefs");
99
- ev.preventDefault();
100
- };
101
- const clickTwoLetter = (ev: Event) => {
102
- selectTab(vnode, 2); // Select tab number 2
103
- ev.preventDefault();
104
- };
105
- const clickNewBag = (ev: Event) => {
106
- selectTab(vnode, 3); // Select tab number 3
107
- ev.preventDefault();
108
- };
109
- let anchors = tabdiv.querySelectorAll("a");
110
- for (let i = 0; i < anchors.length; i++) {
111
- let a = anchors[i];
112
- let href = a.getAttribute("href");
113
- if (href && href.slice(0, ROUTE_PREFIX_LEN) == ROUTE_PREFIX) {
114
- // Single-page URL: wire it up (as if it had had an m.route.Link on it)
115
- a.onclick = (ev) => clickURL(ev, href);
116
- }
117
- else
118
- if (href && href === "$$userprefs$$") {
119
- // Special marker indicating that this link invokes
120
- // a user preference dialog
121
- a.onclick = clickUserPrefs;
122
- }
123
- else
124
- if (href && href === "$$twoletter$$") {
125
- // Special marker indicating that this link invokes
126
- // the two-letter word list or the opponents tab
127
- a.onclick = clickTwoLetter;
128
- }
129
- else
130
- if (href && href === "$$newbag$$") {
131
- // Special marker indicating that this link invokes
132
- // the explanation of the new bag
133
- a.onclick = clickNewBag;
134
- }
135
- }
136
- }
137
- // If a createFunc was specified, run it now
138
- if (createFunc)
139
- createFunc(vnode);
140
- // Finally, make the default tab visible and hide the others
141
- updateTabVisibility(vnode);
142
- }
143
-
144
- function updateTabVisibility(vnode: TabVnode) {
145
- // Shows the tab that is currently selected,
146
- // i.e. the one whose index is in vnode.state.selected
147
- const selected: number = vnode.state.selected;
148
- const lis = vnode.state.lis;
149
- vnode.state.ids.map((id: string, i: number) => {
150
- document.getElementById(id)?.setAttribute("style", "display: " +
151
- (i == selected ? "block" : "none"));
152
- lis[i].classList.toggle("ui-tabs-active", i === selected);
153
- lis[i].classList.toggle("ui-state-active", i === selected);
154
- }
155
- );
156
- }
157
-
158
- export function selectTab(vnode: TabVnode, i: number) {
159
- // Selects the tab with the given index under the tab control vnode
160
- vnode.state.selected = i;
161
- updateTabVisibility(vnode);
162
- }
163
-
164
- export function updateSelection(vnode: TabVnode) {
165
- // Select a tab according to the ?tab= query parameter in the current route
166
- var tab = m.route.param("tab");
167
- if (tab !== undefined)
168
- selectTab(vnode, parseInt(tab) || 0);
169
- }
@@ -1,145 +0,0 @@
1
- /*
2
-
3
- Tile.ts
4
-
5
- Tile component
6
-
7
- Copyright (C) 2025 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 { EXTRA_WIDE_LETTERS, IView, WIDE_LETTERS } from "./types";
17
- import { VnodeAttrs, ComponentFunc, m, MithrilMouseEvent, MithrilTouchEvent } from "./mithril";
18
- import { nbsp } from "./util";
19
- import { startDrag } from "./dragdrop";
20
-
21
- interface IAttributes {
22
- view: IView;
23
- coord: string;
24
- opponent: boolean;
25
- }
26
-
27
- export const Tile: ComponentFunc<IAttributes> = (initialVnode) => {
28
- // Display a tile on the board or in the rack
29
- const { view, coord } = initialVnode.attrs;
30
- const model = view.model;
31
-
32
- const dragHandler = (ev: MithrilMouseEvent | MithrilTouchEvent) => {
33
- // Start a drag-and-drop process, for mouse or touch interaction
34
- startDrag(ev, (_, target) => {
35
- // Drop handler
36
- const game = model.game;
37
- if (!game) return;
38
- const id = target.id;
39
- if (!id) return;
40
- let targetCoord: string = "";
41
- if (id === "board-background") {
42
- // Drop on the background: transfer back to the rack
43
- targetCoord = "R1";
44
- } else if (id.startsWith("sq_")) {
45
- // Drop on a board square
46
- targetCoord = id.slice(3);
47
- }
48
- if (targetCoord) {
49
- try {
50
- game.attemptMove(coord, targetCoord);
51
- view.updateScale();
52
- // Make sure that Mithril draws the updated state
53
- m.redraw();
54
- } catch (e) {
55
- // Something went wrong: display a console error
56
- console.error(e);
57
- }
58
- }
59
- });
60
- ev.redraw = false;
61
- return false;
62
- };
63
-
64
- return {
65
- view: (vnode) => {
66
- const { opponent } = vnode.attrs;
67
- const game = model.game;
68
- if (!game) return undefined;
69
- const isRackTile = coord[0] === 'R';
70
- // A single tile, on the board or in the rack
71
- const t = game.tiles[coord];
72
- let classes = [".tile"];
73
- let attrs: VnodeAttrs = {};
74
- if (t.tile === '?')
75
- classes.push("blanktile");
76
- if (EXTRA_WIDE_LETTERS.includes(t.letter))
77
- // Extra wide letter: handle specially
78
- classes.push("extra-wide");
79
- else if (WIDE_LETTERS.includes(t.letter))
80
- // Wide letter: handle specially
81
- classes.push("wide");
82
- if (isRackTile || t.draggable) {
83
- // Rack tile, or at least a draggable one
84
- classes.push(opponent ? "freshtile" : "racktile");
85
- if (isRackTile && game.showingDialog === "exchange") {
86
- // Rack tile, and we're showing the exchange dialog
87
- if (t.xchg)
88
- // Chosen as an exchange tile
89
- classes.push("xchgsel");
90
- // Exchange dialog is live: add a click handler for the
91
- // exchange state
92
- attrs.onclick = (ev: Event) => {
93
- // Toggle the exchange status of this tile
94
- t.xchg = !t.xchg;
95
- ev.preventDefault();
96
- };
97
- }
98
- } else if (t.freshtile) {
99
- // A fresh tile on the board that has
100
- // just been played by the opponent
101
- classes.push("freshtile");
102
- }
103
- if (t.index) {
104
- // Make fresh or highlighted tiles appear sequentally by animation
105
- const ANIMATION_STEP = 150; // Milliseconds
106
- const delay = (t.index * ANIMATION_STEP).toString() + "ms";
107
- attrs.style = `animation-delay: ${delay}`;
108
- }
109
- if (coord === game.selectedSq)
110
- // Currently selected square
111
- classes.push("sel"); // Blinks red
112
- if (t.highlight !== undefined) {
113
- // highlight0 is the local player color
114
- // highlight1 is the remote player color
115
- classes.push("highlight" + t.highlight);
116
- /*
117
- if (t.player == parseInt(t.highlight))
118
- // This tile was originally laid down by the other player
119
- classes.push("dim");
120
- */
121
- }
122
- if (game.showingDialog === null && !game.over) {
123
- if (t.draggable) {
124
- attrs.onmousedown = dragHandler;
125
- attrs.ontouchstart = dragHandler;
126
- /*
127
- attrs.onclick = (ev: MouseEvent) => {
128
- // When clicking a tile, make it selected (blinking)
129
- if (coord === game.selectedSq)
130
- // Clicking again: deselect
131
- game.selectedSq = null;
132
- else
133
- game.selectedSq = coord;
134
- ev.stopPropagation();
135
- return false;
136
- };
137
- */
138
- }
139
- }
140
- return m(classes.join("."), attrs,
141
- [t.letter === " " ? nbsp() : t.letter, m(".letterscore", t.score)]
142
- );
143
- }
144
- };
145
- }
@@ -1,76 +0,0 @@
1
- /*
2
-
3
- Twoletter.ts
4
-
5
- Two Letter Word display 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 } from "./types";
17
- import { Vnode, ComponentFunc, m, VnodeChildren } from "./mithril";
18
- import { ts } from "./i18n";
19
-
20
- interface IAttributes {
21
- view: IView;
22
- }
23
-
24
- export const TwoLetter: ComponentFunc<IAttributes> = (initialVnode) => {
25
-
26
- // The two-letter-word list tab
27
- const view = initialVnode.attrs.view;
28
- const model = view.model;
29
- let page = 0;
30
-
31
- function renderWord(bold: boolean, w: string): Vnode {
32
- // For the first two-letter word in each group,
33
- // render the former letter in bold
34
- if (!bold)
35
- return m(".twoletter-word", w);
36
- if (page == 0)
37
- return m(".twoletter-word", [m("b", w[0]), w[1]]);
38
- else
39
- return m(".twoletter-word", [w[0], m("b", w[1])]);
40
- }
41
-
42
- return {
43
- view: () => {
44
- if (!model.game) return;
45
- const game = model.game;
46
- const twoLetters = game.twoLetterWords();
47
- const twoLetterWords = twoLetters[page];
48
- const twoLetterList: VnodeChildren = [];
49
- for (const tw of twoLetterWords) {
50
- const twl = tw[1];
51
- const sublist: VnodeChildren = [];
52
- for (let j = 0; j < twl.length; j++)
53
- sublist.push(renderWord(j == 0, twl[j]));
54
- twoLetterList.push(
55
- m(".twoletter-group", sublist)
56
- );
57
- }
58
- return m(".twoletter",
59
- {
60
- // Switch between pages when clicked
61
- onclick: () => { page = 1 - page; },
62
- style: "z-index: 6" // Appear on top of board on mobile
63
- },
64
- // Show the requested page
65
- m(".twoletter-area" + (game.showClock() ? ".with-clock" : ""),
66
- {
67
- title: page == 0 ?
68
- ts("Smelltu til að raða eftir seinni staf") :
69
- ts("Smelltu til að raða eftir fyrri staf")
70
- },
71
- twoLetterList
72
- )
73
- );
74
- }
75
- };
76
- };