Skip to content
This repository has been archived by the owner on Sep 18, 2023. It is now read-only.

Commit

Permalink
draft initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
Ilia Pozdnyakov committed Jun 12, 2023
1 parent 6d1feb5 commit f22edfa
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 3 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
on: push
name: publish
jobs:
build:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v1
with:
path: www
- uses: actions/deploy-pages@v2
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"printWidth": 100
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"build": "./scripts/build.sh",
"watch": "./scripts/watch.sh",
"serve": "http-server ./www"
"serve": "http-server ./www --cors"
},
"repository": {
"type": "git",
Expand Down
88 changes: 87 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,87 @@
console.log("Hello World!");
interface CustomEmoji {
shortcode: string;
url: string;
static_url: string;
visible_in_picker: boolean;
category?: string;
}

async function fetchCustomEmojis(baseUrl: string | URL): Promise<CustomEmoji[]> {
const url = new URL("/api/v1/custom_emojis", baseUrl);
const response = await fetch(url);
const data: CustomEmoji[] = await response.json();
if (!Array.isArray(data)) throw new TypeError();
return data;
}

let _input: HTMLInputElement;
let _container: HTMLElement;

async function updateEmojiInContainer(): Promise<void> {
let baseUrl = _input.value;
if (!baseUrl.startsWith("https://")) baseUrl = "https://" + baseUrl;

const emojis = await fetchCustomEmojis(baseUrl);

const emojisByCategory = new Map<string | undefined, CustomEmoji[]>();

for (const emoji of emojis) {
const categoryEmojis = emojisByCategory.get(emoji.category) ?? [];
categoryEmojis.push(emoji);
emojisByCategory.set(emoji.category, categoryEmojis);
}

const divs = [...emojisByCategory].map(([category, emojis]) => {
const div = document.createElement("div");

const title = document.createElement("h1");
title.innerText = category ?? "(no category)";

const imgs = emojis.map((emoji) => {
const img = document.createElement("img");

img.title = ":" + emoji.shortcode + ":";
img.src = emoji.static_url;
img.dataset.shortcode = emoji.shortcode;

return img;
});

div.replaceChildren(title, ...imgs);

return div;
});

_container.replaceChildren(...divs);
}

export interface Options {
input: HTMLInputElement;
container: HTMLElement;
initialUrl: string | undefined;
}

export async function register(options: Options) {
_input = options.input;
_container = options.container;

if (options.initialUrl) {
_input.value = options.initialUrl;
}

if (_input.value) {
updateEmojiInContainer().catch((e) => console.log(e));
}

_input.onpaste = _input.onsubmit = () => {
setTimeout(() => updateEmojiInContainer().catch((e) => console.log(e)), 0);
};

_container.onclick = (e) => {
const target = e.target;
if (!(target instanceof HTMLImageElement)) return;

const shortcode = target.dataset.shortcode;
navigator.clipboard.writeText(":" + shortcode + ":");
};
}
20 changes: 19 additions & 1 deletion www/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Mastodon Emoji Picker</title>
<link rel="stylesheet" href="style.css" />
<script src="index.js"></script>
<script>
window.onload = () => {
EmojiPicker.register({
input: document.getElementById("url-input"),
container: document.getElementById("emojis-container"),
initialUrl: document.referrer,
});
};
</script>
</head>
<body></body>
<body>
<label for="url-input">Paste your instance URL here:</label>
<input id="url-input" type="text" placeholder="e.g. https://mastodon.social" />
<p>Click on an emoji to copy its code to clipboard.</p>
<div id="emojis-container"></div>
</body>
</html>
25 changes: 25 additions & 0 deletions www/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#emojis-container img {
width: 64px;
height: 64px;

margin: 10px;

cursor: pointer;

transition-property: width, height, margin;
transition-duration: 0.2s;
}

#emojis-container img:hover {
width: 80px;
height: 80px;

margin: 2px;
}

#emojis-container img:active {
width: 70px;
height: 70px;

margin: 7px;
}

0 comments on commit f22edfa

Please sign in to comment.