57 |
58 | {['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'].map((key) => (
59 |
66 | ))}
67 |
68 |
69 | {['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'].map((key) => (
70 |
77 | ))}
78 |
79 |
80 |
81 | {ENTER_TEXT}
82 |
83 | {['Z', 'X', 'C', 'V', 'B', 'N', 'M'].map((key) => (
84 |
91 | ))}
92 |
93 | {DELETE_TEXT}
94 |
95 |
96 |
97 | )
98 | }
99 |
--------------------------------------------------------------------------------
/backend/src/channels.ts:
--------------------------------------------------------------------------------
1 | import "@feathersjs/transport-commons";
2 | import { HookContext } from "@feathersjs/feathers";
3 | import { Application } from "./declarations";
4 |
5 | export default function (app: Application): void {
6 | if (typeof app.channel !== "function") {
7 | // If no real-time functionality has been configured just return
8 | return;
9 | }
10 |
11 | app.on("connection", (connection: any): void => {
12 | // On a new real-time connection, add it to the anonymous channel
13 | app.channel("anonymous").join(connection);
14 | });
15 |
16 | app.on("login", (authResult: any, { connection }: any): void => {
17 | // connection can be undefined if there is no
18 | // real-time connection, e.g. when logging in via REST
19 | if (connection) {
20 | // Obtain the logged in user from the connection
21 | // const user = connection.user;
22 |
23 | // The connection is no longer anonymous, remove it
24 | app.channel("anonymous").leave(connection);
25 |
26 | // Add it to the authenticated user channel
27 | app.channel("authenticated").join(connection);
28 |
29 | // Channels can be named anything and joined on any condition
30 |
31 | // E.g. to send real-time events only to admins use
32 | // if(user.isAdmin) { app.channel('admins').join(connection); }
33 |
34 | // If the user has joined e.g. chat rooms
35 | // if(Array.isArray(user.rooms)) user.rooms.forEach(room => app.channel(`rooms/${room.id}`).join(connection));
36 |
37 | // Easily organize users by email and userid for things like messaging
38 | // app.channel(`emails/${user.email}`).join(connection);
39 | // app.channel(`userIds/${user.id}`).join(connection);
40 | }
41 | });
42 |
43 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
44 | app.publish((data: any, hook: HookContext) => {
45 | // Here you can add event publishers to channels set up in `channels.ts`
46 | // To publish only for a specific event use `app.publish(eventname, () => {})`
47 |
48 | console.log(
49 | "Publishing all events to all authenticated users. See `channels.ts` and https://docs.feathersjs.com/api/channels.html for more information."
50 | ); // eslint-disable-line
51 |
52 | // e.g. to publish all service events to all authenticated users use
53 | return app.channel("authenticated");
54 | });
55 |
56 | // Here you can also add service specific event publishers
57 | // e.g. the publish the `users` service `created` event to the `admins` channel
58 | // app.service('users').publish('created', () => app.channel('admins'));
59 |
60 | // With the userid and email organization from above you can easily select involved users
61 | // app.service('messages').publish(() => {
62 | // return [
63 | // app.channel(`userIds/${data.createdBy}`),
64 | // app.channel(`emails/${data.recipientEmail}`)
65 | // ];
66 | // });
67 | }
68 |
--------------------------------------------------------------------------------
/frontend/src/lib/share.ts:
--------------------------------------------------------------------------------
1 | import { CharStatus } from './statuses'
2 | import { unicodeSplit } from './words'
3 | import { GAME_TITLE } from '../constants/strings'
4 | import { MAX_CHALLENGES } from '../constants/settings'
5 | import { UAParser } from 'ua-parser-js'
6 | import { Groth16Proof } from '../zk/prove'
7 |
8 | const webShareApiDeviceTypes: string[] = ['mobile', 'smarttv', 'wearable']
9 | const parser = new UAParser()
10 | const browser = parser.getBrowser()
11 | const device = parser.getDevice()
12 |
13 | export const shareStatus = (
14 | solutionIndex: number,
15 | proof: Groth16Proof,
16 | guesses: string[],
17 | statuses: Map