Skip to content

Commit

Permalink
Merge pull request #27 from aiden2480/replit-refactor
Browse files Browse the repository at this point in the history
Remove replit dependency
  • Loading branch information
aiden2480 authored Apr 6, 2024
2 parents 77cdfc0 + 0dcd39f commit 52d67b6
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 183 deletions.
61 changes: 12 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,38 @@
<a href="https://github.com/aiden2480/kanjithing/commits"><img src="https://img.shields.io/github/last-commit/aiden2480/kanjithing?color=red" title="GitHub commit history" /></a>
<a href="https://chrome.google.com/webstore/detail/kanjithing/nccfelhkfpbnefflolffkclhenplhiab/reviews"><img src="https://img.shields.io/chrome-web-store/rating/nccfelhkfpbnefflolffkclhenplhiab?color=orange" title="Google chrome store rating" /></a>
<a href="https://chrome.google.com/webstore/detail/kanjithing/nccfelhkfpbnefflolffkclhenplhiab"><img src="https://img.shields.io/chrome-web-store/v/nccfelhkfpbnefflolffkclhenplhiab?color=yellow" title="Last version published on chrome web store" /></a>
<a href="https://github.com/aiden2480/kanjithing/actions/workflows/updatewebstore.yml"><img src="https://img.shields.io/github/workflow/status/aiden2480/kanjithing/Publish%20to%20chrome%20webstore?label=Publish%20workflow&color=green" title="Webstore publish workflow status" /></a>
<a href="https://github.com/aiden2480/kanjithing/actions/workflows/updatewebstore.yml"><img src="https://img.shields.io/github/actions/workflow/status/aiden2480/kanjithing/updatewebstore.yml?branch=main&label=Publish%20workflow&color=green" title="Webstore publish workflow status" /></a>
<a href="https://github.com/aiden2480/kanjithing/blob/main/LICENCE"><img src="https://img.shields.io/github/license/aiden2480/kanjithing?color=blue" /></a>
<a href="https://aiden2480.github.io/kanjithing/"><img src="https://img.shields.io/badge/GitHub%20Pages-active-af6eeb" /></a>
</div>

## :shrug: A google chrome extension for practising kanji
You can practise drawing kanji featured in the Wakatta units. That's pretty much it right now.
You can practise drawing kanji featured in the Wakatta units. It also has other useful information like character readings and example words.
> [Install on the google chrome webstore](https://chrome.google.com/webstore/detail/kanjithing/nccfelhkfpbnefflolffkclhenplhiab)
## :gear: Installation
> The extension is available in the [google chrome store](https://chrome.google.com/webstore/detail/nccfelhkfpbnefflolffkclhenplhiab), though it can be installed from source with the following instructions
1. [Download the repository as a zip](https://github.com/aiden2480/kanjithing/zipball/main) and extract
1. `git clone https://github.com/aiden2480/kanjithing`
2. Navigate to [`chrome://extensions`](chrome://extensions)
3. Ensure that the `Developer mode` switch is enabled in the top right of your screen
4. Click `Load unpacked` in the top left corner of the screen
5. Select the folder containing the extension in the popup modal

## :recycle: Update
Google chrome will automatically update the extension as I publish new updates if you install from the chrome store.
If installing from this repository, `git clone` this repository and then run `git pull origin master` yourself.
You'll need to go back into the [chrome extension settings](chrome://extensions) and press the refresh icon next to the extension to reload.
If installing from this repository, run `git pull origin main`, then go back to `chrome://extensions` and press the refresh icon next to the extension to reload.

I'm using a [custom GitHub action](.github/workflows/updatewebstore.yml) to automatically publish new versions of the extension to the chrome store every time I change the `version` parameter in the `manifest.json` file.

## :file_cabinet: API
The kanji drawing guide videos are sourced from [KanjiAlive](https://app.kanjialive.com/api/docs), and cached using a [middleman I created](https://replit.com/@chocolatejade42/kanjithing-backend) (as RapidAPI limits requests).
It also collates some data about the kanji which is used in the extension, such as readings, and example words.
Requests can be made at the `/kanji/:kanji` endpoint, like so.

```bash
$ curl -L http://kanjithing-backend.chocolatejade42.repl.co/kanji/車
```
```json
{
"status": 200,
"kanji": "",
"kstroke": 7,
"kmeaning": "vehicle, wheel, car",
"kgrade": 1,
"kunyomi_ja": "くるま",
"onyomi_ja": "シャ",
"video": "https://media.kanjialive.com/kanji_animations/kanji_mp4/kuruma_00.mp4",
"examples": [
["車(くるま)", "car"],
["電車(でんしゃ)", "train"],
["自転車(じてんしゃ)", "bicycle"],
["自動車(じどうしゃ)", "automobile"],
["車いす(くるまいす)", "wheel chair"],
["駐車する(ちゅうしゃする)", "park a car"],
["停車する(ていしゃする)", "stop a car or train"]
]
}
```
## :camera_flash: Program screenshots
<img src="https://lh3.googleusercontent.com/NuTuEgPEhh0LpGCkyzcpZvysRrbiI5Y7Wer7tKPLJx-O0HkLHaveUPUCabzpWn9s5daCH9Jt3dY-OjheGamEMeCL1A=s1600-w1600-h1000" />
<img src="https://lh3.googleusercontent.com/XFupiSqYq2YRvOoleYBKZpoZ15Ec2COgMR4oRejduc5XaK-NMbEK8hYBaWd4AA5_f8836Jhv0EXEMuhsKNXn1_-bHA=s1600-w1600-h1000" />
<img src="https://lh3.googleusercontent.com/zglUDkiGKA18ixPKbC0tSKLL2RJeyyoo6srT_i-ggDvysBHNigntwECpjzjjW5suLwdX4n8vkkFko8b3c6ymqdvB=s1600-w1600-h1000" />

## :memo: Future features
- [ ] Able to star/favourite kanji to add them quickly to a custom set.
- [ ] Make the user guess readings of kanji in words
- [ ] Help page
- How to use the extention, info about tooltips, etc
- Open on the first install
- [ ] Flashcard thing where you get the meaning of the kanji and sample words and have to draw it
- [ ] Custom flashcards to remember kanji/words
- Import from quizlet
Expand All @@ -77,20 +48,12 @@ $ curl -L http://kanjithing-backend.chocolatejade42.repl.co/kanji/車
- [ ] Right click to remove drawing (all connected strokes)
- [ ] Add tooltip banner when extension updates
- Potentially as a small subtext badge?
- [x] Keybinds to navigate the application via keyboard
- Up/down arrow to navigate between kanji sets
- Left/right arrow to navigate between kanji in the currently selected set
- R to select a random kanji in the currently selected set
- Enter to grade kanji drawing
- Space to play/pause/replay video guide
- Backspace to clear drawing
- S to star/unstar selected kanji
- Keybinds visible in tooltips
- [ ] Use static assets for the emojis to keep design consistent between operating systems
- [ ] Event listener on the popup script to determine when the set storage has changed
- [ ] Use data from the KanjiAlive API to do pronuncation/sounds
- [ ] Make CSS for buttons/inputs be consistent throughout the popup/settings/index pages
- [x] Make CSS for buttons/inputs be consistent throughout the popup/settings/index pages
- [ ] Fix overlap interaction with especially long word descriptions (同 kanji)
- [x] Use a RapidAPI key in the application to fetch data (Replit downtime)
- [ ] Unspaghettify everything
- [ ] Add method of actually accessing the tips page
- [ ] Display notice if character data not available
- [ ] https://github.com/gildas-lormeau/zip.js/tree/master/dist
- [ ] https://github.com/kanjialive/kanji-data-media/blob/master/kanji-animations/animations-mp4.zip
63 changes: 38 additions & 25 deletions background.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* Save the current kanji */
var current;
/* Default sets for the initial installation */
var defaultsets = [
{"Unit one": "学校名前父母生高姉妹兄弟住所色"},
{"Unit two": "好同手紙英語何年私友行毎教場"},
Expand Down Expand Up @@ -51,14 +50,13 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {(async
case "resetKanjiSets":
await chrome.storage.local.remove("customsets");
await createKanjiSets();
sendResponse();
break;
case "ensureDefaultConfig":
await ensureDefaultConfiguration();
sendResponse();
break;
}

sendResponse();
})(); return true});

/* Set up a listener for when the extension is installed/chrome restarts */
Expand All @@ -71,9 +69,10 @@ chrome.runtime.onInstalled.addListener(async reason => {
await chrome.storage.local.set({ selectedkanji: 0 });
}

if ((await chrome.management.getSelf()).installType !== "development")
chrome.runtime.setUninstallURL("https://kanjithing-backend.chocolatejade42.repl.co/uninstall");

if (!await isDevelopment()) {
chrome.runtime.setUninstallURL("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
}

// Register context menus
chrome.contextMenus.removeAll(() => {
generateContextMenus();
Expand All @@ -92,7 +91,9 @@ chrome.runtime.onStartup.addListener(async () => {

chrome.storage.onChanged.addListener(async (changes, namespace) => {
// Console log when storage values change
if ((await chrome.management.getSelf()).installType !== "development") return;
if (!await isDevelopment()) {
return;
}

for (let [key, { oldValue, newValue }] of Object.entries(changes)) {
console.debug(`${key} : ${oldValue} -> ${newValue}`);
Expand All @@ -107,14 +108,14 @@ async function ensureCorrectKanjiIcon() {
var { customsets, selectedset, selectedkanji } = await chrome.storage.local.get();
if ([ customsets, selectedset, selectedkanji ].includes(undefined)) return;

setBrowserIcon(customsets[selectedset].kanji[selectedkanji], bypass=true);
setBrowserIcon(customsets[selectedset].kanji[selectedkanji]);
}

/**
* Ensures the "Beta" badge is displayed if necessary
*/
async function ensureBetaBadge() {
if ((await chrome.management.getSelf()).installType === "development") {
if (await isDevelopment()) {
chrome.action.setBadgeText({ text: "B" });
chrome.action.setBadgeBackgroundColor({ color: "#304db6" });
}
Expand All @@ -126,24 +127,27 @@ async function ensureBetaBadge() {
*/
async function ensureDefaultConfiguration() {
// Create default sets
var sets = (await chrome.storage.local.get("customsets")).customsets;
(sets === undefined) && await createKanjiSets();
var { customsets } = await chrome.storage.local.get("customsets");

if (customsets === undefined) {
await createKanjiSets();
}

// Create default settings
var { config } = await chrome.storage.local.get("config");
(config === undefined) && await createDefaultConfig();

if (config === undefined) {
await createDefaultConfig();
}
}

/**
* Sets the browser icon to the currently selected character
*
* @param {Char} kanji The character to set the browser icon to
* @param {Boolean} bypass Bypass same-kanji check
*/
function setBrowserIcon(kanji, bypass=false) {
function setBrowserIcon(kanji) {
// https://jsfiddle.net/1u37ovj9/
if (current === kanji && !bypass) return;

var canvas = new OffscreenCanvas(64, 64);
var context = canvas.getContext("2d");

Expand All @@ -157,7 +161,6 @@ function setBrowserIcon(kanji, bypass=false) {
context.fillStyle = "#FFFAFA";
context.fillText(kanji, 0.5 * canvas.width, 0.825 * canvas.height);

current = kanji;
var imageData = context.getImageData(0, 0, 64, 64);
chrome.action.setIcon({ imageData }, () => console.log(`Set browser icon to %c${kanji}`, "color: #7289da"));
}
Expand Down Expand Up @@ -238,32 +241,32 @@ chrome.contextMenus.onClicked.addListener(async (info, tab) => {

// Show a little x for a second if an error occured
if (!match) return await displayBadge(tab, "X", "#D9381E", 3000);
var sets = (await chrome.storage.local.get("customsets")).customsets;
var { customsets } = await chrome.storage.local.get("customsets");

if (info.menuItemId === "createnewset") {
sets.push({
id: sets.slice(-1)[0].id + 1,
customsets.push({
id: customsets.slice(-1)[0].id + 1,
name: "Unnamed set",
kanji: match,
enabled: true
});

await chrome.storage.local.set({ customsets: sets });
await chrome.storage.local.set({ customsets });
await displayBadge(tab, "✓", "#32CD32", 3000);

if (isPopup) await chrome.storage.local.set({
selectedunit: sets.at(-1).id,
selectedunit: customsets.at(-1).id,
selectedkanji: 0,
});
}

if (info.menuItemId.startsWith("addtoset")) {
var setid = info.menuItemId.match(/addtoset(.+)/)[1];

var set = sets.find(x => x.id == setid);
var set = customsets.find(x => x.id == setid);
set.kanji += match;

await chrome.storage.local.set({ customsets: sets });
await chrome.storage.local.set({ customsets });
await displayBadge(tab, "✓", "#32CD32", 3000);

if (isPopup) await chrome.storage.local.set({
Expand Down Expand Up @@ -303,3 +306,13 @@ async function displayBadge(tab, text, colour, milliseconds) {
await chrome.action.setBadgeText({ text: current.text });
}, milliseconds);
}

/**
*
* @returns A boolean indicating if the current installation context is dev
*/
async function isDevelopment() {
var { installType } = await chrome.management.getSelf();

return installType === "development";
}
1 change: 1 addition & 0 deletions css/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ div#panel * {
background-color: #36393e;
color: #7289da;
border: 2px solid #7289da;
cursor: pointer;
}

#panel > select { height: 23px; }
Expand Down
Loading

0 comments on commit 52d67b6

Please sign in to comment.