Release v1.1.3: Emoji Picker for List Customization

Added visual emoji picker for customizing list icons:
- 1,800+ emojis across 13 categories (smileys, hearts, animals, food, activities, travel, tech, office, music, symbols, flags)
- Searchable with 130+ keyword mappings (e.g., "smile", "heart", "work", "fire")
- Responsive modal design that fits viewport (85vw max 400px, 80vh max height)
- Visual selection with highlight for current emoji
- Category organization with scrollable display
- Custom emoji input option
- Mobile-friendly touch targets (32px buttons)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-25 19:36:57 +01:00
parent 264441f83b
commit 271780f48a
8 changed files with 932 additions and 31 deletions

View File

@@ -22,7 +22,7 @@ import {
import { ImmerseView } from './view';
import { ReportView, VIEW_TYPE_REPORT } from './reportView';
import { QuickAddTaskModal } from './modals';
import { QuickAddTaskModal, EmojiPickerModal } from './modals';
// ============ Main Plugin Class ============
@@ -1385,12 +1385,20 @@ class ImmerseSettingTab extends PluginSettingTab {
this.plugin.settings.lists[index].name = value;
await this.plugin.saveAllData();
}))
.addText(text => text
.setValue(list.icon)
.setPlaceholder('Emoji')
.onChange(async value => {
this.plugin.settings.lists[index].icon = value;
await this.plugin.saveAllData();
.addButton(btn => btn
.setButtonText(list.icon || '📁')
.setTooltip('Choose emoji')
.onClick(() => {
const modal = new EmojiPickerModal(
this.app,
list.icon,
async (emoji) => {
this.plugin.settings.lists[index].icon = emoji;
await this.plugin.saveAllData();
this.display();
}
);
modal.open();
}))
.addColorPicker(picker => picker
.setValue(list.color)

View File

@@ -8,6 +8,293 @@ import {
import { ImmerseTask } from './types';
import ImmersePlugin from './main';
// Emoji search keywords mapping
const EMOJI_KEYWORDS: { [key: string]: string } = {
'💼': 'briefcase work business office job',
'🏠': 'home house',
'📚': 'books study read library',
'🎯': 'target goal aim dart',
'✅': 'check mark done complete checkbox tick',
'📝': 'memo note write pencil',
'💡': 'light bulb idea',
'🔥': 'fire hot flame',
'⚡': 'lightning bolt electric zap',
'🎨': 'art paint palette',
'🏆': 'trophy award win',
'💪': 'muscle strong flex',
'🚀': 'rocket ship launch',
'📊': 'chart graph data',
'⏰': 'clock time alarm',
'💰': 'money bag cash dollar',
'😀': 'smile happy face grin',
'😃': 'smile happy grin',
'😄': 'smile happy laugh',
'😁': 'grin smile happy',
'😆': 'laugh smile happy',
'😅': 'sweat smile nervous',
'🤣': 'laugh rolling floor',
'😂': 'tears joy laugh cry',
'🙂': 'smile happy slight',
'🙃': 'upside down smile',
'😉': 'wink smile flirt',
'😊': 'blush smile happy',
'😇': 'angel halo smile',
'🥰': 'love hearts smile',
'😍': 'love heart eyes smile',
'🤩': 'star eyes excited',
'😘': 'kiss love heart',
'😗': 'kiss love',
'😚': 'kiss love',
'😙': 'kiss love smile',
'🥲': 'smile tear cry happy',
'😋': 'yum delicious smile',
'😛': 'tongue playful',
'😜': 'wink tongue playful',
'🤪': 'crazy wild eyes',
'😝': 'tongue eyes squint',
'🤑': 'money dollar rich',
'🤗': 'hug smile',
'🤭': 'hand over mouth giggle',
'🤫': 'shush quiet secret',
'🤔': 'think hmm wonder',
'🤐': 'zipper mouth secret',
'🤨': 'eyebrow raised skeptical',
'😐': 'neutral meh',
'😑': 'expressionless blank',
'😶': 'no mouth silent',
'😏': 'smirk confident',
'😒': 'unamused annoyed',
'🙄': 'eye roll annoyed',
'😬': 'grimace awkward',
'🤥': 'liar lying pinocchio',
'😌': 'relieved content',
'😔': 'sad pensive',
'😪': 'sleepy tired',
'🤤': 'drool sleep',
'😴': 'sleep zzz',
'😷': 'mask sick medical',
'🤒': 'sick thermometer',
'🤕': 'injured bandage',
'🤢': 'nausea sick',
'🤮': 'vomit sick',
'🤧': 'sneeze sick tissue',
'🥵': 'hot sweat',
'🥶': 'cold freeze',
'😎': 'cool sunglasses',
'🤓': 'nerd glasses',
'🧐': 'monocle fancy',
'😕': 'confused uncertain',
'😟': 'worried concerned',
'🙁': 'frown sad',
'☹️': 'frown sad',
'😮': 'wow surprised',
'😯': 'surprised shocked',
'😲': 'shocked astonished',
'😳': 'flushed embarrassed',
'🥺': 'pleading puppy eyes',
'😦': 'frown worried',
'😧': 'anguished worried',
'😨': 'fearful scared',
'😰': 'anxious sweat',
'😥': 'sad sweat',
'😢': 'cry tear sad',
'😭': 'cry tears sob',
'😱': 'scream fear',
'😖': 'confounded',
'😣': 'persevere struggle',
'😞': 'disappointed sad',
'😓': 'downcast sweat',
'😩': 'weary tired',
'😫': 'tired exhausted',
'🥱': 'yawn tired',
'😤': 'triumph proud',
'😡': 'angry mad rage',
'😠': 'angry mad',
'🤬': 'cursing swearing angry',
'😈': 'devil smiling evil',
'👿': 'devil angry evil',
'💀': 'skull death',
'☠️': 'skull crossbones death',
'💩': 'poop poo',
'🤡': 'clown funny',
'👹': 'ogre monster',
'👺': 'goblin monster',
'👻': 'ghost boo',
'👽': 'alien extraterrestrial',
'👾': 'alien monster game',
'🤖': 'robot bot',
'❤️': 'red heart love',
'🧡': 'orange heart love',
'💛': 'yellow heart love',
'💚': 'green heart love',
'💙': 'blue heart love',
'💜': 'purple heart love',
'🤎': 'brown heart love',
'🖤': 'black heart love',
'🤍': 'white heart love',
'💔': 'broken heart sad',
'❣️': 'heart exclamation love',
'💕': 'two hearts love',
'💞': 'revolving hearts love',
'💓': 'beating heart love',
'💗': 'growing heart love',
'💖': 'sparkling heart love',
'💘': 'arrow heart love cupid',
'💝': 'heart box gift love',
'💟': 'heart decoration love',
'❤️‍🔥': 'heart fire love passion',
'❤️‍🩹': 'heart bandage healing',
'💌': 'love letter heart',
'💋': 'kiss lips',
'💑': 'couple love kiss',
'💏': 'kiss couple love',
'👋': 'wave hand hello goodbye',
'🤚': 'raised hand back',
'🖐️': 'hand fingers spread',
'✋': 'raised hand stop',
'🖖': 'vulcan salute spock',
'👌': 'ok okay hand',
'🤌': 'pinched fingers italian',
'🤏': 'pinching hand small',
'✌️': 'peace victory hand',
'🤞': 'crossed fingers luck',
'🤟': 'love you hand',
'🤘': 'rock on horns',
'🤙': 'call me hang loose',
'👈': 'left point finger',
'👉': 'right point finger',
'👆': 'up point finger',
'🖕': 'middle finger rude',
'👇': 'down point finger',
'☝️': 'up point finger',
'👍': 'thumbs up yes good',
'👎': 'thumbs down no bad',
'✊': 'fist hand',
'👊': 'fist bump punch',
'🤛': 'left fist bump',
'🤜': 'right fist bump',
'👏': 'clap applause',
'🙌': 'raising hands celebration',
'👐': 'open hands',
'🤲': 'palms together pray',
'🤝': 'handshake deal',
'🙏': 'pray please thank',
'✍️': 'writing hand',
'💅': 'nail polish manicure',
'🤳': 'selfie camera phone',
'🐶': 'dog puppy pet',
'🐱': 'cat kitty pet',
'🐭': 'mouse rat',
'🐹': 'hamster pet',
'🐰': 'rabbit bunny',
'🦊': 'fox',
'🐻': 'bear',
'🐼': 'panda bear',
'🐨': 'koala bear',
'🐯': 'tiger face',
'🦁': 'lion face',
'🐮': 'cow face',
'🐷': 'pig face',
'🐸': 'frog face',
'🐵': 'monkey face',
'🍎': 'apple red fruit',
'🍊': 'orange fruit',
'🍋': 'lemon fruit',
'🍌': 'banana fruit',
'🍉': 'watermelon fruit',
'🍇': 'grapes fruit',
'🍓': 'strawberry fruit',
'🍒': 'cherry fruit',
'🍑': 'peach fruit',
'🥭': 'mango fruit',
'🍍': 'pineapple fruit',
'🥥': 'coconut fruit',
'🥝': 'kiwi fruit',
'🍅': 'tomato vegetable',
'🥑': 'avocado fruit',
'🍞': 'bread food',
'⚽': 'soccer ball football',
'🏀': 'basketball ball',
'🏈': 'american football',
'⚾': 'baseball ball',
'🎾': 'tennis ball',
'🏐': 'volleyball ball',
'🚗': 'car auto vehicle',
'🚕': 'taxi car',
'🚙': 'suv car vehicle',
'🚌': 'bus vehicle',
'🚎': 'trolleybus bus',
'🏎️': 'racing car fast',
'🚓': 'police car cop',
'🚑': 'ambulance emergency',
'🚒': 'fire truck engine',
'🚲': 'bicycle bike',
'✈️': 'airplane plane flight',
'💻': 'laptop computer',
'⌨️': 'keyboard computer',
'🖱️': 'mouse computer',
'🖥️': 'desktop computer',
'🖨️': 'printer',
'📱': 'phone mobile iphone',
'📞': 'phone telephone',
'☎️': 'telephone phone',
'📺': 'tv television',
'📻': 'radio',
'📁': 'folder file',
'📂': 'open folder file',
'📅': 'calendar date',
'📆': 'calendar date',
'📈': 'chart up graph',
'📉': 'chart down graph',
'📌': 'pushpin pin',
'📍': 'pin location map',
'📎': 'paperclip clip',
'🎵': 'music note',
'🎶': 'music notes',
'🎼': 'musical score',
'🎹': 'piano keyboard music',
'🎸': 'guitar music',
'🎺': 'trumpet music',
'🎷': 'saxophone music',
'🥁': 'drum music',
'🎤': 'microphone mic sing',
'🎧': 'headphones music',
'🔊': 'speaker loud volume',
'❌': 'cross x no cancel',
'⚠️': 'warning caution alert',
'🔴': 'red circle',
'🟢': 'green circle',
'🔵': 'blue circle',
'🟡': 'yellow circle',
'🟣': 'purple circle',
'⚫': 'black circle',
'⚪': 'white circle',
'🟤': 'brown circle',
'🔺': 'triangle red up',
'🔻': 'triangle red down',
'🔸': 'diamond orange small',
'🔹': 'diamond blue small',
'🔶': 'diamond orange large',
'🔷': 'diamond blue large',
};
// Emoji categories for picker
const EMOJI_CATEGORIES = {
'⭐ Frequently Used': ['💼', '🏠', '📚', '🎯', '✅', '📝', '💡', '🔥', '⚡', '🎨', '🏆', '💪', '🚀', '📊', '⏰', '💰'],
'😀 Smileys & Emotion': ['😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃', '😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗', '😚', '😙', '🥲', '😋', '😛', '😜', '🤪', '😝', '🤑', '🤗', '🤭', '🤫', '🤔', '🤐', '🤨', '😐', '😑', '😶', '😏', '😒', '🙄', '😬', '🤥', '😌', '😔', '😪', '🤤', '😴', '😷', '🤒', '🤕', '🤢', '🤮', '🤧', '🥵', '🥶', '😎', '🤓', '🧐', '😕', '😟', '🙁', '☹️', '😮', '😯', '😲', '😳', '🥺', '😦', '😧', '😨', '😰', '😥', '😢', '😭', '😱', '😖', '😣', '😞', '😓', '😩', '😫', '🥱', '😤', '😡', '😠', '🤬', '😈', '👿', '💀', '☠️', '💩', '🤡', '👹', '👺', '👻', '👽', '👾', '🤖'],
'❤️ Hearts & Love': ['❤️', '🧡', '💛', '💚', '💙', '💜', '🤎', '🖤', '🤍', '💔', '❣️', '💕', '💞', '💓', '💗', '💖', '💘', '💝', '💟', '❤️‍🔥', '❤️‍🩹', '💌', '💋', '💑', '💏', '👩‍❤️‍👨', '👨‍❤️‍👨', '👩‍❤️‍👩'],
'👤 People & Body': ['👋', '🤚', '🖐️', '✋', '🖖', '👌', '🤌', '🤏', '✌️', '🤞', '🤟', '🤘', '🤙', '👈', '👉', '👆', '🖕', '👇', '☝️', '👍', '👎', '✊', '👊', '🤛', '🤜', '👏', '🙌', '👐', '🤲', '🤝', '🙏', '✍️', '💅', '🤳', '💪', '🦾', '🦿', '🦵', '🦶', '👂', '🦻', '👃', '🧠', '🫀', '🫁', '🦷', '🦴', '👀', '👁️', '👅', '👄', '👶', '🧒', '👦', '👧', '🧑', '👨', '👩', '🧔', '🧑‍🦰', '👨‍🦰', '👩‍🦰', '🧑‍🦱', '👨‍🦱', '👩‍🦱', '🧑‍🦳', '👨‍🦳', '👩‍🦳', '🧑‍🦲', '👨‍🦲', '👩‍🦲', '👱', '👱‍♂️', '👱‍♀️', '🧓', '👴', '👵', '🙍', '🙍‍♂️', '🙍‍♀️', '🙎', '🙎‍♂️', '🙎‍♀️', '🙅', '🙅‍♂️', '🙅‍♀️', '🙆', '🙆‍♂️', '🙆‍♀️', '💁', '💁‍♂️', '💁‍♀️', '🙋', '🙋‍♂️', '🙋‍♀️', '🧏', '🧏‍♂️', '🧏‍♀️', '🙇', '🙇‍♂️', '🙇‍♀️', '🤦', '🤦‍♂️', '🤦‍♀️', '🤷', '🤷‍♂️', '🤷‍♀️'],
'🐶 Animals & Nature': ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯', '🦁', '🐮', '🐷', '🐽', '🐸', '🐵', '🙈', '🙉', '🙊', '🐒', '🐔', '🐧', '🐦', '🐤', '🐣', '🐥', '🦆', '🦅', '🦉', '🦇', '🐺', '🐗', '🐴', '🦄', '🐝', '🐛', '🦋', '🐌', '🐞', '🐜', '🦟', '🦗', '🕷️', '🕸️', '🦂', '🐢', '🐍', '🦎', '🦖', '🦕', '🐙', '🦑', '🦐', '🦞', '🦀', '🐡', '🐠', '🐟', '🐬', '🐳', '🐋', '🦈', '🐊', '🐅', '🐆', '🦓', '🦍', '🦧', '🐘', '🦛', '🦏', '🐪', '🐫', '🦒', '🦘', '🐃', '🐂', '🐄', '🐎', '🐖', '🐏', '🐑', '🦙', '🐐', '🦌', '🐕', '🐩', '🦮', '🐕‍🦺', '🐈', '🐈‍⬛', '🐓', '🦃', '🦚', '🦜', '🦢', '🦩', '🕊️', '🐇', '🦝', '🦨', '🦡', '🦦', '🦥', '🐁', '🐀', '🐿️', '🦔', '🌲', '🌳', '🌴', '🌱', '🌿', '☘️', '🍀', '🎍', '🎋', '🍃', '🍂', '🍁', '🍄', '🌾', '💐', '🌷', '🌹', '🥀', '🌺', '🌸', '🌼', '🌻', '🌞', '🌝', '🌛', '🌜', '🌚', '🌕', '🌖', '🌗', '🌘', '🌑', '🌒', '🌓', '🌔', '🌙', '🌎', '🌍', '🌏', '🪐', '💫', '⭐', '🌟', '✨', '⚡', '☄️', '💥', '🔥', '🌪️', '🌈', '☀️', '🌤️', '⛅', '🌥️', '☁️', '🌦️', '🌧️', '⛈️', '🌩️', '🌨️', '❄️', '☃️', '⛄', '🌬️', '💨', '💧', '💦', '☔', '☂️', '🌊', '🌫️'],
'🍎 Food & Drink': ['🍇', '🍈', '🍉', '🍊', '🍋', '🍌', '🍍', '🥭', '🍎', '🍏', '🍐', '🍑', '🍒', '🍓', '🫐', '🥝', '🍅', '🫒', '🥥', '🥑', '🍆', '🥔', '🥕', '🌽', '🌶️', '🫑', '🥒', '🥬', '🥦', '🧄', '🧅', '🍄', '🥜', '🌰', '🍞', '🥐', '🥖', '🫓', '🥨', '🥯', '🥞', '🧇', '🧀', '🍖', '🍗', '🥩', '🥓', '🍔', '🍟', '🍕', '🌭', '🥪', '🌮', '🌯', '🫔', '🥙', '🧆', '🥚', '🍳', '🥘', '🍲', '🫕', '🥣', '🥗', '🍿', '🧈', '🧂', '🥫', '🍱', '🍘', '🍙', '🍚', '🍛', '🍜', '🍝', '🍠', '🍢', '🍣', '🍤', '🍥', '🥮', '🍡', '🥟', '🥠', '🥡', '🦀', '🦞', '🦐', '🦑', '🦪', '🍦', '🍧', '🍨', '🍩', '🍪', '🎂', '🍰', '🧁', '🥧', '🍫', '🍬', '🍭', '🍮', '🍯', '🍼', '🥛', '☕', '🫖', '🍵', '🍶', '🍾', '🍷', '🍸', '🍹', '🍺', '🍻', '🥂', '🥃', '🥤', '🧋', '🧃', '🧉', '🧊'],
'⚽ Activities & Sports': ['⚽', '🏀', '🏈', '⚾', '🥎', '🎾', '🏐', '🏉', '🥏', '🎱', '🪀', '🏓', '🏸', '🏒', '🏑', '🥍', '🏏', '🪃', '🥅', '⛳', '🪁', '🏹', '🎣', '🤿', '🥊', '🥋', '🎽', '🛹', '🛼', '🛷', '⛸️', '🥌', '🎿', '⛷️', '🏂', '🪂', '🏋️', '🏋️‍♂️', '🏋️‍♀️', '🤼', '🤼‍♂️', '🤼‍♀️', '🤸', '🤸‍♂️', '🤸‍♀️', '⛹️', '⛹️‍♂️', '⛹️‍♀️', '🤺', '🤾', '🤾‍♂️', '🤾‍♀️', '🏌️', '🏌️‍♂️', '🏌️‍♀️', '🏇', '🧘', '🧘‍♂️', '🧘‍♀️', '🏄', '🏄‍♂️', '🏄‍♀️', '🏊', '🏊‍♂️', '🏊‍♀️', '🤽', '🤽‍♂️', '🤽‍♀️', '🚣', '🚣‍♂️', '🚣‍♀️', '🧗', '🧗‍♂️', '🧗‍♀️', '🚵', '🚵‍♂️', '🚵‍♀️', '🚴', '🚴‍♂️', '🚴‍♀️', '🏆', '🥇', '🥈', '🥉', '🏅', '🎖️', '🏵️', '🎗️', '🎫', '🎟️', '🎪', '🤹', '🤹‍♂️', '🤹‍♀️', '🎭', '🩰', '🎨', '🎬', '🎤', '🎧', '🎼', '🎹', '🥁', '🪘', '🎷', '🎺', '🪗', '🎸', '🪕', '🎻', '🎲', '♟️', '🎯', '🎳', '🎮', '🎰', '🧩'],
'🚗 Travel & Places': ['🚗', '🚕', '🚙', '🚌', '🚎', '🏎️', '🚓', '🚑', '🚒', '🚐', '🛻', '🚚', '🚛', '🚜', '🦯', '🦽', '🦼', '🛴', '🚲', '🛵', '🏍️', '🛺', '🚨', '🚔', '🚍', '🚘', '🚖', '🚡', '🚠', '🚟', '🚃', '🚋', '🚞', '🚝', '🚄', '🚅', '🚈', '🚂', '🚆', '🚇', '🚊', '🚉', '✈️', '🛫', '🛬', '🛩️', '💺', '🛰️', '🚀', '🛸', '🚁', '🛶', '⛵', '🚤', '🛥️', '🛳️', '⛴️', '🚢', '⚓', '⛽', '🚧', '🚦', '🚥', '🚏', '🗺️', '🗿', '🗽', '🗼', '🏰', '🏯', '🏟️', '🎡', '🎢', '🎠', '⛲', '⛱️', '🏖️', '🏝️', '🏜️', '🌋', '⛰️', '🏔️', '🗻', '🏕️', '⛺', '🛖', '🏠', '🏡', '🏘️', '🏚️', '🏗️', '🏭', '🏢', '🏬', '🏣', '🏤', '🏥', '🏦', '🏨', '🏪', '🏫', '🏩', '💒', '🏛️', '⛪', '🕌', '🕍', '🛕', '🕋', '⛩️', '🛤️', '🛣️', '🗾', '🎑', '🏞️', '🌅', '🌄', '🌠', '🎇', '🎆', '🌇', '🌆', '🏙️', '🌃', '🌌', '🌉', '🌁'],
'💻 Objects & Technology': ['⌚', '📱', '📲', '💻', '⌨️', '🖥️', '🖨️', '🖱️', '🖲️', '🕹️', '🗜️', '💾', '💿', '📀', '📼', '📷', '📸', '📹', '🎥', '📽️', '🎞️', '📞', '☎️', '📟', '📠', '📺', '📻', '🎙️', '🎚️', '🎛️', '🧭', '⏱️', '⏲️', '⏰', '🕰️', '⌛', '⏳', '📡', '🔋', '🔌', '💡', '🔦', '🕯️', '🪔', '🧯', '🛢️', '💸', '💵', '💴', '💶', '💷', '🪙', '💰', '💳', '💎', '⚖️', '🪜', '🧰', '🪛', '🔧', '🔨', '⚒️', '🛠️', '⛏️', '🪚', '🔩', '⚙️', '🪤', '🧱', '⛓️', '🧲', '🔫', '💣', '🧨', '🪓', '🔪', '🗡️', '⚔️', '🛡️', '🚬', '⚰️', '🪦', '⚱️', '🏺', '🔮', '📿', '🧿', '💈', '⚗️', '🔭', '🔬', '🕳️', '🩹', '🩺', '💊', '💉', '🩸', '🧬', '🦷', '🧪', '🌡️', '🧹', '🪠', '🧺', '🧻', '🚽', '🚰', '🚿', '🛁', '🛀', '🧼', '🪥', '🪒', '🧽', '🪣', '🧴', '🛎️', '🔑', '🗝️', '🚪', '🪑', '🛋️', '🛏️', '🛌', '🧸', '🪆', '🖼️', '🪞', '🪟', '🛍️', '🛒', '🎁', '🎈', '🎏', '🎀', '🪄', '🪅', '🎊', '🎉', '🎎', '🏮', '🎐', '🧧'],
'📋 Office & Writing': ['✉️', '📧', '📨', '📩', '📤', '📥', '📦', '📫', '📪', '📬', '📭', '📮', '🗳️', '✏️', '✒️', '🖋️', '🖊️', '🖌️', '🖍️', '📝', '💼', '📁', '📂', '🗂️', '📅', '📆', '🗒️', '🗓️', '📇', '📈', '📉', '📊', '📋', '📌', '📍', '📎', '🖇️', '📏', '📐', '✂️', '🗃️', '🗄️', '🗑️', '🔒', '🔓', '🔏', '🔐', '🔑', '🗝️', '🔨', '🪓', '⛏️', '⚒️', '🛠️', '🗡️', '⚔️', '💣', '🪃', '🏹', '🛡️', '🪚', '🔧', '🪛', '🔩', '⚙️', '🗜️', '⚖️'],
'🎵 Music & Sound': ['🎵', '🎶', '🎼', '🎹', '🎸', '🎺', '🎷', '🥁', '🪘', '🎤', '🎧', '📻', '🎙️', '🔊', '🔉', '🔈', '🔇', '📢', '📣', '📯', '🔔', '🔕', '🎚️', '🎛️', '🎖️', '🏆', '🥇', '🥈', '🥉', '⚡', '🔥', '💥'],
'⚡ Symbols & Signs': ['❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '🤍', '🤎', '💔', '❣️', '💕', '💞', '💓', '💗', '💖', '💘', '💝', '💟', '☮️', '✝️', '☪️', '🕉️', '☸️', '✡️', '🔯', '🕎', '☯️', '☦️', '🛐', '⛎', '♈', '♉', '♊', '♋', '♌', '♍', '♎', '♏', '♐', '♑', '♒', '♓', '🆔', '⚛️', '🉑', '☢️', '☣️', '📴', '📳', '🈶', '🈚', '🈸', '🈺', '🈷️', '✴️', '🆚', '💮', '🉐', '㊙️', '㊗️', '🈴', '🈵', '🈹', '🈲', '🅰️', '🅱️', '🆎', '🆑', '🅾️', '🆘', '❌', '⭕', '🛑', '⛔', '📛', '🚫', '💯', '💢', '♨️', '🚷', '🚯', '🚳', '🚱', '🔞', '📵', '🚭', '❗', '❕', '❓', '❔', '‼️', '⁉️', '🔅', '🔆', '〽️', '⚠️', '🚸', '🔱', '⚜️', '🔰', '♻️', '✅', '🈯', '💹', '❇️', '✳️', '❎', '🌐', '💠', 'Ⓜ️', '🌀', '💤', '🏧', '🚾', '♿', '🅿️', '🛗', '🈳', '🈂️', '🛂', '🛃', '🛄', '🛅', '🚹', '🚺', '🚼', '⚧️', '🚻', '🚮', '🎦', '📶', '🈁', '🔣', '', '🔤', '🔡', '🔠', '🆖', '🆗', '🆙', '🆒', '🆕', '🆓', '0⃣', '1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣', '9⃣', '🔟', '🔢', '#️⃣', '*️⃣', '⏏️', '▶️', '⏸️', '⏯️', '⏹️', '⏺️', '⏭️', '⏮️', '⏩', '⏪', '⏫', '⏬', '◀️', '🔼', '🔽', '➡️', '⬅️', '⬆️', '⬇️', '↗️', '↘️', '↙️', '↖️', '↕️', '↔️', '↪️', '↩️', '⤴️', '⤵️', '🔀', '🔁', '🔂', '🔄', '🔃', '🎵', '🎶', '', '', '➗', '✖️', '♾️', '💲', '💱', '™️', '©️', '®️', '〰️', '➰', '➿', '🔚', '🔙', '🔛', '🔝', '🔜', '✔️', '☑️', '🔘', '🔴', '🟠', '🟡', '🟢', '🔵', '🟣', '⚫', '⚪', '🟤', '🔺', '🔻', '🔸', '🔹', '🔶', '🔷', '🔳', '🔲', '▪️', '▫️', '◾', '◽', '◼️', '◻️', '🟥', '🟧', '🟨', '🟩', '🟦', '🟪', '⬛', '⬜', '🟫', '🔈', '🔇', '🔉', '🔊', '🔔', '🔕', '📣', '📢', '💬', '💭', '🗯️', '♠️', '♣️', '♥️', '♦️', '🃏', '🎴', '🀄', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛', '🕜', '🕝', '🕞', '🕟', '🕠', '🕡', '🕢', '🕣', '🕤', '🕥', '🕦', '🕧'],
'🏁 Flags': ['🏁', '🚩', '🎌', '🏴', '🏳️', '🏳️‍🌈', '🏳️‍⚧️', '🏴‍☠️', '🇦🇨', '🇦🇩', '🇦🇪', '🇦🇫', '🇦🇬', '🇦🇮', '🇦🇱', '🇦🇲', '🇦🇴', '🇦🇶', '🇦🇷', '🇦🇸', '🇦🇹', '🇦🇺', '🇦🇼', '🇦🇽', '🇦🇿', '🇧🇦', '🇧🇧', '🇧🇩', '🇧🇪', '🇧🇫', '🇧🇬', '🇧🇭', '🇧🇮', '🇧🇯', '🇧🇱', '🇧🇲', '🇧🇳', '🇧🇴', '🇧🇶', '🇧🇷', '🇧🇸', '🇧🇹', '🇧🇻', '🇧🇼', '🇧🇾', '🇧🇿', '🇨🇦', '🇨🇨', '🇨🇩', '🇨🇫', '🇨🇬', '🇨🇭', '🇨🇮', '🇨🇰', '🇨🇱', '🇨🇲', '🇨🇳', '🇨🇴', '🇨🇵', '🇨🇷', '🇨🇺', '🇨🇻', '🇨🇼', '🇨🇽', '🇨🇾', '🇨🇿', '🇩🇪', '🇩🇬', '🇩🇯', '🇩🇰', '🇩🇲', '🇩🇴', '🇩🇿', '🇪🇦', '🇪🇨', '🇪🇪', '🇪🇬', '🇪🇭', '🇪🇷', '🇪🇸', '🇪🇹', '🇪🇺', '🇫🇮', '🇫🇯', '🇫🇰', '🇫🇲', '🇫🇴', '🇫🇷', '🇬🇦', '🇬🇧', '🇬🇩', '🇬🇪', '🇬🇫', '🇬🇬', '🇬🇭', '🇬🇮', '🇬🇱', '🇬🇲', '🇬🇳', '🇬🇵', '🇬🇶', '🇬🇷', '🇬🇸', '🇬🇹', '🇬🇺', '🇬🇼', '🇬🇾', '🇭🇰', '🇭🇲', '🇭🇳', '🇭🇷', '🇭🇹', '🇭🇺', '🇮🇨', '🇮🇩', '🇮🇪', '🇮🇱', '🇮🇲', '🇮🇳', '🇮🇴', '🇮🇶', '🇮🇷', '🇮🇸', '🇮🇹', '🇯🇪', '🇯🇲', '🇯🇴', '🇯🇵', '🇰🇪', '🇰🇬', '🇰🇭', '🇰🇮', '🇰🇲', '🇰🇳', '🇰🇵', '🇰🇷', '🇰🇼', '🇰🇾', '🇰🇿', '🇱🇦', '🇱🇧', '🇱🇨', '🇱🇮', '🇱🇰', '🇱🇷', '🇱🇸', '🇱🇹', '🇱🇺', '🇱🇻', '🇱🇾', '🇲🇦', '🇲🇨', '🇲🇩', '🇲🇪', '🇲🇫', '🇲🇬', '🇲🇭', '🇲🇰', '🇲🇱', '🇲🇲', '🇲🇳', '🇲🇴', '🇲🇵', '🇲🇶', '🇲🇷', '🇲🇸', '🇲🇹', '🇲🇺', '🇲🇻', '🇲🇼', '🇲🇽', '🇲🇾', '🇲🇿', '🇳🇦', '🇳🇨', '🇳🇪', '🇳🇫', '🇳🇬', '🇳🇮', '🇳🇱', '🇳🇴', '🇳🇵', '🇳🇷', '🇳🇺', '🇳🇿', '🇴🇲', '🇵🇦', '🇵🇪', '🇵🇫', '🇵🇬', '🇵🇭', '🇵🇰', '🇵🇱', '🇵🇲', '🇵🇳', '🇵🇷', '🇵🇸', '🇵🇹', '🇵🇼', '🇵🇾', '🇶🇦', '🇷🇪', '🇷🇴', '🇷🇸', '🇷🇺', '🇷🇼', '🇸🇦', '🇸🇧', '🇸🇨', '🇸🇩', '🇸🇪', '🇸🇬', '🇸🇭', '🇸🇮', '🇸🇯', '🇸🇰', '🇸🇱', '🇸🇲', '🇸🇳', '🇸🇴', '🇸🇷', '🇸🇸', '🇸🇹', '🇸🇻', '🇸🇽', '🇸🇾', '🇸🇿', '🇹🇦', '🇹🇨', '🇹🇩', '🇹🇫', '🇹🇬', '🇹🇭', '🇹🇯', '🇹🇰', '🇹🇱', '🇹🇲', '🇹🇳', '🇹🇴', '🇹🇷', '🇹🇹', '🇹🇻', '🇹🇼', '🇹🇿', '🇺🇦', '🇺🇬', '🇺🇲', '🇺🇳', '🇺🇸', '🇺🇾', '🇺🇿', '🇻🇦', '🇻🇨', '🇻🇪', '🇻🇬', '🇻🇮', '🇻🇳', '🇻🇺', '🇼🇫', '🇼🇸', '🇽🇰', '🇾🇪', '🇾🇹', '🇿🇦', '🇿🇲', '🇿🇼', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', '🏴󠁧󠁢󠁳󠁣󠁴󠁿', '🏴󠁧󠁢󠁷󠁬󠁳󠁿'],
};
// ============ Quick Add Task Modal ============
export class QuickAddTaskModal extends Modal {
@@ -547,4 +834,115 @@ export class ReportModal extends Modal {
const { contentEl } = this;
contentEl.empty();
}
}
}
// ============ Emoji Picker Modal ============
export class EmojiPickerModal extends Modal {
onSelect: (emoji: string) => void;
currentEmoji: string;
constructor(app: App, currentEmoji: string, onSelect: (emoji: string) => void) {
super(app);
this.currentEmoji = currentEmoji;
this.onSelect = onSelect;
}
onOpen() {
const { contentEl } = this;
contentEl.addClass('immerse-emoji-picker');
contentEl.createEl('h2', { text: 'Select Emoji' });
// Current selection
if (this.currentEmoji) {
const currentDiv = contentEl.createDiv({ cls: 'immerse-emoji-current' });
currentDiv.createEl('span', { text: 'Current: ' });
currentDiv.createEl('span', { text: this.currentEmoji, cls: 'immerse-emoji-current-icon' });
}
// Search box
const searchContainer = contentEl.createDiv({ cls: 'immerse-emoji-search' });
const searchInput = searchContainer.createEl('input', {
type: 'text',
placeholder: 'Search emojis...',
cls: 'immerse-emoji-search-input'
});
// Emoji grid container
const gridContainer = contentEl.createDiv({ cls: 'immerse-emoji-categories' });
// Render all categories
const renderCategories = (filter: string = '') => {
gridContainer.empty();
Object.entries(EMOJI_CATEGORIES).forEach(([category, emojis]) => {
const filteredEmojis = filter
? emojis.filter(emoji => {
const keywords = EMOJI_KEYWORDS[emoji] || '';
return keywords.toLowerCase().includes(filter) || emoji.includes(filter);
})
: emojis;
if (filteredEmojis.length === 0) return;
const categoryDiv = gridContainer.createDiv({ cls: 'immerse-emoji-category' });
categoryDiv.createEl('h3', { text: category, cls: 'immerse-emoji-category-title' });
const grid = categoryDiv.createDiv({ cls: 'immerse-emoji-grid' });
filteredEmojis.forEach(emoji => {
const button = grid.createEl('button', {
text: emoji,
cls: 'immerse-emoji-button'
});
if (emoji === this.currentEmoji) {
button.addClass('immerse-emoji-selected');
}
button.addEventListener('click', () => {
this.onSelect(emoji);
this.close();
});
});
});
};
// Initial render
renderCategories();
// Search functionality
searchInput.addEventListener('input', (e) => {
const filter = (e.target as HTMLInputElement).value.toLowerCase();
renderCategories(filter);
});
// Custom emoji input
const customDiv = contentEl.createDiv({ cls: 'immerse-emoji-custom' });
customDiv.createEl('span', { text: 'Or enter custom emoji: ' });
const customInput = customDiv.createEl('input', {
type: 'text',
placeholder: 'Paste emoji',
cls: 'immerse-emoji-custom-input',
});
const customBtn = customDiv.createEl('button', {
text: 'Use Custom',
cls: 'immerse-btn immerse-btn-primary'
});
customBtn.addEventListener('click', () => {
const customEmoji = customInput.value.trim();
if (customEmoji) {
this.onSelect(customEmoji);
this.close();
}
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
}