add "Create a game" button

This commit is contained in:
blek 2023-09-03 22:38:05 +10:00
parent 40eac5d01f
commit a56e33b9f2
Signed by: blek
GPG Key ID: 14546221E3595D0C
9 changed files with 156 additions and 3 deletions

View File

@ -2,5 +2,5 @@
<p align="center">
<img src="https://jenkins.blek.codes/job/bWordle/badge/icon?style=plastic"></img>
</p>
OpenWordle is a completely open source and lightweight wordle game with no runtime dependencies
OpenWordle is a completely open source and lightweight wordle game with very minimal set of runtime dependencies

View File

@ -19,5 +19,9 @@
"typescript": "^5.0.2",
"vite": "^4.4.5",
"vite-plugin-compression": "^0.5.1"
},
"dependencies": {
"copy-to-clipboard": "^3.3.3",
"qr-creator": "^1.0.0"
}
}

View File

@ -10,6 +10,8 @@
import { isIn, loadDict } from "./dictionary";
import { onMount } from "svelte";
import Keyboard from "./Keyboard.svelte";
import GameCreator from "./GameCreator.svelte";
import { decode } from "./lib/cipher";
let targets = getForNWord(5);
@ -23,12 +25,22 @@
let loading = true;
let not_a_word = false;
let game_creator = false;
let green_letters: string[] = [];
let yellow_letters: string[] = [];
let unfit_letters: string[] = [];
console.log(word);
(
function() {
const urlprops = new URLSearchParams(window.location.search);
const challenge = urlprops.get('challenge');
if (challenge !== null) {
word = decode(atob(decodeURIComponent(challenge)));
console.log(word)
}
}
)()
onMount(async () => {
await loadDict();
@ -130,6 +142,8 @@
}
</script>
<GameCreator bind:show={game_creator} />
{#if not_a_word}
<Modal show animate={false}>
<ModalTitle>
@ -174,6 +188,10 @@
Give up
</button>
<button on:click={() => {game_creator = true}}>
Create a game
</button>
<p style='line-height:0;margin-top:48px'>
{#each guessed as g1, i}
{#each g1 as letter, ii}

69
src/GameCreator.svelte Normal file
View File

@ -0,0 +1,69 @@
<script lang='ts'>
import { onMount } from "svelte";
import Modal from "./modal/Modal.svelte";
import ModalButton from "./modal/ModalButton.svelte";
import ModalContent from "./modal/ModalContent.svelte";
import ModalFooter from "./modal/ModalFooter.svelte";
import ModalTitle from "./modal/ModalTitle.svelte";
import { encode } from "./lib/cipher";
import { getRandom } from "./targets";
export let show = false;
let word = getRandom(5);
let qrurl: string | false = false;
let wordurl = '';
let qrcanvas: HTMLCanvasElement;
async function upd_qr() {
if (word == '') return;
if (!qrcanvas) return;
wordurl = `${window.location.protocol}//${window.location.host}?challenge=${encodeURIComponent(btoa(encode(word)))}`;
const QrCreator = (await import('qr-creator')).default;
QrCreator.render({
text: wordurl,
radius: 0.5,
ecLevel: 'L',
fill: '#000000',
background: '#ffffff',
size: 120
}, qrcanvas);
}
async function copylink() {
const copy = (await import('copy-to-clipboard')).default;
copy(wordurl);
}
onMount(async () => {
await upd_qr();
})
</script>
{#if show}
<Modal show>
<ModalTitle>
Create a game
</ModalTitle>
<ModalContent>
<p>
Word:
<input type='text' bind:value={word} on:input={upd_qr}>
</p>
<p style='min-height:160px'>
<span style='border-radius:12px;padding:20px;background:white;display:inline-block'>
<canvas bind:this={qrcanvas} width="120px" height="122px" style='border-radius:4px' />
</span>
</p>
</ModalContent>
<ModalFooter>
<ModalButton style='width:50%;border-right:0;border-radius:0 0 0 16px' onclick={() => {show = false; word = getRandom(5); upd_qr()}}>
Close
</ModalButton>
<ModalButton style='width:50%;border-radius:0 0 16px 0' onclick={copylink}>
Copy link
</ModalButton>
</ModalFooter>
</Modal>
{/if}

View File

@ -43,6 +43,18 @@ button:active {
background: #161616;
}
input[type=text] {
background: #181818;
border: 1px solid #343434;
border-radius: 6px;
margin: 0 4px;
padding: 4px 6px;
outline: none;
min-width: 80px;
width: 80px;
max-width: 100%;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;

22
src/lib/cipher.ts Normal file
View File

@ -0,0 +1,22 @@
import { random } from "./random";
export function encode(word: string) {
let out = '';
for (const letter of word) {
out += String.fromCharCode(random(32, 128)) + letter;
}
return out
}
export function decode(ciphertext: string) {
let out = '';
for (let i = 0; i != ciphertext.length; i++) {
if (i % 2 == 1) {
out += ciphertext[i];
}
}
return out;
}
globalThis.encode = encode;
globalThis.decode = decode;

View File

@ -11,4 +11,14 @@ export function getForNWord(len: number) {
return out
}
export function getRandom(len: number | null = null) {
const dataset = len ? getForNWord(len) : targets;
for (const target of dataset) {
if (random(0, Math.floor(dataset.length * 0.5)) == 0) {
return target;
}
}
return dataset[0];
}
export default targets

3
src/vite-env.d.ts vendored
View File

@ -1,3 +1,4 @@
/// <reference types="svelte" />
/// <reference types="vite/client" />
const TARGETS: string
const TARGETS: string;
declare module 'qr-creator';

View File

@ -333,6 +333,13 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
copy-to-clipboard@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0"
integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==
dependencies:
toggle-selection "^1.0.6"
css-tree@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
@ -670,6 +677,11 @@ postcss@^8.4.27:
picocolors "^1.0.0"
source-map-js "^1.0.2"
qr-creator@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/qr-creator/-/qr-creator-1.0.0.tgz#f350a8f0b5be02bd1fc1ef133a038a06ef8bc5ef"
integrity sha512-C0cqfbS1P5hfqN4NhsYsUXePlk9BO+a45bAQ3xLYjBL3bOIFzoVEjs79Fado9u9BPBD3buHi3+vY+C8tHh4qMQ==
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@ -815,6 +827,11 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
toggle-selection@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==
tslib@^2.6.0:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"