Skip to content

SimplGy/emoji-magic

Repository files navigation

Emoji Magic

Find Emoji using keywords.

gif in action

Inspired by the ease of use of mojibar.

Born of a desire to improve emoji searching even further.

How to Use

  1. Click the extension icon: ๐Ÿ”ฎ
  2. Type what you want, like "cat"
  3. Hit "enter" or click on the exact emoji you want

Tip: choose a keyboard shortcut in chrome://extensions/shortcuts -> Emoji Magic so you can add Emojis easily, anytime.

Features

1898 total unique emoji supported, Up to Unicode Emoji version 15.1.

  1. ๐Ÿ”ง Actual Unicode Chars -- Native emoji rendering, no big slow images
  2. ๐Ÿ“˜ Rich Text Matching -- Finds synonyms using a thesaurus
  3. ๐Ÿ”— Multi-word Queries -- Try "sad cat", or "blue heart"
  4. ๐Ÿง  Remembers locally -- Saves the last emoji you picked so you can pick them again easily
  5. ๐Ÿ”’ Strong security -- No dangerous Chrome permissions, just clipboard access

Extension Security

This app requires absolutely minimal permissions.

  1. Only clipboard access
  2. No background script

Some other emoji extensions I've seen want to "read and change the data on all the sites you visit".

These permissions are unsafe and unnecessary for a emoji picker. Read more about Chrome extension safety: 1, 2, 3.

Developing

Serve the local repo for live editing and a fast dev experience:

# run in repo root:
python3 -m http.server 8080

# To view the demo version of the app with a "website" wrapper:
# http://0.0.0.0:8080/src/

# To view the "details" for a specific emoji, use it's code point(s):
# http://0.0.0.0:8080/src/emoji.html?128153

# To view the raw browser action "app":
# http://0.0.0.0:8080/src/browser_action.html

Compile SASS into css:

# Use VSCode's SASS live watch plugin, or...
sass --update src/app_ui/emoji_picker.sass src/site/site.sass

Run Tests:

npm test

Run live watching tests (needs npm i -g nodemon):

nodemon --exec npm test

Procedure: Adding new manual keywords

  1. verify you're unhappy with existing keywords by searching file emojilib_thesaurus.js
  2. add it to MANUAL_KEYWORDS in scripts/thesaurus.js
  3. run node scripts/thesaurus

Procedure: Updating the Emoji Data (~yearly when new Unicode emoji are available)

(You may need a one-time npm i to install dev dependencies)

  1. Note current version of emoji support
    1. run node scripts/show-unicode-versions. latest version: 13.1
    2. Note current version of unicode: 16.0.
    3. Example new emoji: "root vegetable"
  2. run node scripts/update-3p to update and regenerate the third_party local raw data for this app (emoji-en-US.json and data-by-emoji.json)
    1. This depends on an upstream project https://github.com/muan/unicode-emoji-json
    2. The upstream project provides unicode metadata and some manual keywords
    3. It is not always up-to-date (eg: 2024 september, does not have 16.0). It's probably more up to date than this project, but it's not 100% real time.
    4. check the diff after you run this to make sure it's WAI. Some of the added keywords are fun (eg: "slay" for painting nails.)
  3. run node scripts/thesaurus to re-generate the main data file used by the app (emojilib_thesaurus.js)
  4. run node scripts/show-unicode-versions again to verify there is new content
  5. Do commit that contains all of emoji-en-US.json, data-by-emoji.json, and emojilib_thesaurus.js.
  6. test in the web ui (dev instructions above)
    1. note: I think you have to do a "hard refresh" (cmd+shift+r) to pick up the new large edited thesaurus file

If you're happy with the results, bump the manifest version and follow the steps in the "Deploying" section.

Procedure: Test as an unpacked chrome extension

Create an extension-deployable zip file and unpack it for local testing with Chrome:

rm -rf ./dist/emoji-magic && node scripts/zip && unzip -o ./dist/emoji-magic.zip -d ./dist/emoji-magic
# test by using "load unpacked extension" in Chrome

Deploying the Chrome extension

  1. bump manifest_version
  2. Create an extension-deployable zip file node scripts/zip
  3. Go to Chrome's extension devconsole
  4. Add release notes for the update
  5. upload the new zip file and "submit for review"

Deploying static "web app"

Build the "web app" demo version to docs/ (so named for Github Pages):

node scripts/to-docs
# test with `serve docs` or similar local web server

Then just commit and push, Github will do the rest.

About the folders

  • dist -- dist bundle for chrome extention
  • docs -- for the demo web app. Called "docs" for Github Static Pages. Don't modify things here. Modify src, then run the build step.
  • src -- this is the only source code you should be editing

Uh, what's up with the crazy module system?

I wanted an environment that works in:

  1. The Browser (for web app and demo)
  2. Chrome Extension (for the main use case)
  3. Node (for tests)

I also didn't want a build system, for... reasons (for fun). And also just the dependencies they involve, and the complexity... just didn't seem worth it. So, that's what emulate_node_modules.js is about. It works just fine, so long as you add an __id__ for every module that matches the file name, and don't make a module that has the same name as a different one.

Extension Development Gripes

Three Environments

When building one of these, I think most developers will want to do testing on the command line with Node, rapid development with live reload in the browser, and of course must deploy to a Chrome extension target.

I have had no end of bugs that only exhibit on one or another of these platforms. Sometimes it's only broken when run in an extension context. Sometimes only in node for tests.

Most extensions are simple and adding a rollup/webpack build system seems like a lot of overhead that isn't deserved, but it's hard to avoid. Would be nice for Chrome to get opinionated about this and make a happy path Typescript/test/local dev environment for extensions that is impossible to mess up.

Contributing

Contributions welcome. See CONTRIBUTING.md.

Fun

Distribution of new emojis in each Unicode version since v3:

15.1   (28)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
15.0   (21)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
14.0   (37)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
13.1   (7)   โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
13.0   (67)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
12.1   (23)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
12.0   (75)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
11.0   (77)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
5.0    (79)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
4.0    (113) โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
3.0    (72)  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ

Technical Design

Dead simple version: Just return everything that contains the search query anywhere inside keywords or icon name.

  1. break search into tokens
  2. prefix match each token

Thanks and Credits

Disclaimer

This is not an officially supported Google product.

About

๐Ÿ”ฎ Find emojis easily

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages