Release 1.1.0: switch to dewemoji.com and simplify account UI
This commit is contained in:
@@ -4,7 +4,7 @@ This checklist verifies extension behavior against current backend flow.
|
||||
|
||||
## Preconditions
|
||||
- Extension loaded in Chrome (unpacked).
|
||||
- Backend reachable at `https://api.dewemoji.com/v1`.
|
||||
- Backend reachable at `https://dewemoji.com/v1`.
|
||||
- Backend deployed with extension search route:
|
||||
- `GET /v1/extension/search`
|
||||
- Browser DevTools available for network/console checks.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Dewemoji - Emojis Made Effortless",
|
||||
"description": "Find and copy emojis instantly. Optional Pro license unlocks tone lock, insert mode, and more.",
|
||||
"version": "1.0.2",
|
||||
"description": "Find and copy emojis instantly. Connect your account to use private keywords across web and extension.",
|
||||
"version": "1.1.0",
|
||||
"offline_enabled": false,
|
||||
"permissions": [
|
||||
"storage",
|
||||
@@ -12,8 +12,7 @@
|
||||
],
|
||||
"host_permissions": [
|
||||
"<all_urls>",
|
||||
"https://dewemoji.backoffice.biz.id/*",
|
||||
"https://api.dewemoji.com/*"
|
||||
"https://dewemoji.com/*"
|
||||
],
|
||||
"web_accessible_resources": [
|
||||
{
|
||||
|
||||
44
panel.html
44
panel.html
@@ -87,33 +87,33 @@
|
||||
<div id="tab-pro" class="tabpane">
|
||||
<div class="field">
|
||||
<label class="lbl">Account</label>
|
||||
<div class="row">
|
||||
<input id="account-email" class="inp" placeholder="Email" type="email" autocomplete="username">
|
||||
<div id="account-connect-form">
|
||||
<div class="row">
|
||||
<input id="account-email" class="inp" placeholder="Email" type="email" autocomplete="username">
|
||||
</div>
|
||||
<div class="row" style="margin-top:6px;">
|
||||
<input id="account-password" class="inp" placeholder="Password" type="password" autocomplete="current-password">
|
||||
</div>
|
||||
<div class="row">
|
||||
<button id="account-login" class="btn">Connect</button>
|
||||
</div>
|
||||
<div class="row" style="margin-top:6px;">
|
||||
<span id="account-status" class="muted">Not connected. Public keywords only.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top:6px;">
|
||||
<input id="account-password" class="inp" placeholder="Password" type="password" autocomplete="current-password">
|
||||
</div>
|
||||
<div class="row">
|
||||
<button id="account-login" class="btn">Connect</button>
|
||||
<button id="account-logout" class="btn ghost">Logout</button>
|
||||
</div>
|
||||
<div class="row" style="margin-top:6px;">
|
||||
<span id="account-status" class="muted">Not connected. Public keywords only.</span>
|
||||
|
||||
<div id="account-connected" style="display:none;">
|
||||
<div class="row">
|
||||
<span id="account-greeting" class="muted">Connected.</span>
|
||||
</div>
|
||||
<div class="row" style="margin-top:8px;">
|
||||
<button id="account-logout" class="btn ghost">Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tone settings are injected here by panel.js -->
|
||||
|
||||
<!-- Diagnostics -->
|
||||
<div class="field">
|
||||
<label class="lbl">Extension Health</label>
|
||||
<div class="row">
|
||||
<button id="diag-run" class="btn">Run health check</button>
|
||||
<span id="diag-spin" class="muted" style="display:none;">Running…</span>
|
||||
</div>
|
||||
<div id="diag-out" class="diagbox muted"></div>
|
||||
<p class="hint muted">Tip: Click in a text box on the page first, then run health check.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -136,6 +136,6 @@
|
||||
</div>
|
||||
|
||||
<div id="toast" class="toast" role="status" aria-live="polite"></div>
|
||||
<script src="panel.js?ver=1.0.1"></script>
|
||||
<script src="panel.js?ver=1.1.0"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
61
panel.js
61
panel.js
@@ -7,6 +7,7 @@ let licenseKeyCurrent = '';
|
||||
let authApiKey = '';
|
||||
let authTier = 'guest'; // guest | free | personal
|
||||
let authEmail = '';
|
||||
let authName = '';
|
||||
|
||||
// Tone settings (persisted in sync storage)
|
||||
let toneLock = false; // if true, always use preferred tone
|
||||
@@ -29,6 +30,9 @@ const accountPasswordEl = document.getElementById('account-password');
|
||||
const accountLoginBtn = document.getElementById('account-login');
|
||||
const accountLogoutBtn = document.getElementById('account-logout');
|
||||
const accountStatusEl = document.getElementById('account-status');
|
||||
const accountGreetingEl = document.getElementById('account-greeting');
|
||||
const accountConnectFormEl = document.getElementById('account-connect-form');
|
||||
const accountConnectedEl = document.getElementById('account-connected');
|
||||
|
||||
// --- Branded confirm modal helper ---
|
||||
function showConfirmModal(opts = {}) {
|
||||
@@ -113,12 +117,8 @@ function setLicenseBusy(on, label){
|
||||
}
|
||||
}
|
||||
|
||||
const diagRunBtn = document.getElementById('diag-run');
|
||||
const diagSpin = document.getElementById('diag-spin');
|
||||
const diagOut = document.getElementById('diag-out');
|
||||
|
||||
const API = {
|
||||
base: "https://dewemoji.backoffice.biz.id/v1",
|
||||
base: "https://dewemoji.com/v1",
|
||||
list: "/emojis"
|
||||
};
|
||||
API.cats = "/categories";
|
||||
@@ -650,8 +650,7 @@ function getListPaths(){
|
||||
function getApiBases(){
|
||||
const list = [
|
||||
API.base,
|
||||
'https://dewemoji.backoffice.biz.id/v1',
|
||||
'https://api.dewemoji.com/v1',
|
||||
'https://dewemoji.com/v1',
|
||||
'http://127.0.0.1:8000/v1',
|
||||
];
|
||||
const seen = new Set();
|
||||
@@ -1233,13 +1232,14 @@ loadCategories().catch(console.error);
|
||||
})();
|
||||
|
||||
async function loadSettings() {
|
||||
const data = await chrome.storage.local.get(['actionMode', 'authApiKey', 'authTier', 'authEmail']);
|
||||
const data = await chrome.storage.local.get(['actionMode', 'authApiKey', 'authTier', 'authEmail', 'authName']);
|
||||
licenseValid = true;
|
||||
refreshPageLimit();
|
||||
actionMode = data.actionMode || 'copy';
|
||||
authApiKey = data.authApiKey || '';
|
||||
authTier = data.authTier || 'guest';
|
||||
authEmail = data.authEmail || '';
|
||||
authName = data.authName || '';
|
||||
if (accountEmailEl && authEmail) accountEmailEl.value = authEmail;
|
||||
applyLicenseUI();
|
||||
applyModeUI();
|
||||
@@ -1253,7 +1253,7 @@ async function loadSettings() {
|
||||
}
|
||||
|
||||
async function saveSettings() {
|
||||
await chrome.storage.local.set({ licenseValid: true, actionMode, authApiKey, authTier, authEmail });
|
||||
await chrome.storage.local.set({ licenseValid: true, actionMode, authApiKey, authTier, authEmail, authName });
|
||||
}
|
||||
|
||||
// --- Helper to render Free status with CTA ---
|
||||
@@ -1305,6 +1305,8 @@ function updateAccountUI() {
|
||||
if (!accountStatusEl) return;
|
||||
if (!authApiKey) {
|
||||
accountStatusEl.textContent = 'Not connected. Public keywords only.';
|
||||
if (accountConnectFormEl) accountConnectFormEl.style.display = '';
|
||||
if (accountConnectedEl) accountConnectedEl.style.display = 'none';
|
||||
if (accountLoginBtn) {
|
||||
accountLoginBtn.disabled = false;
|
||||
accountLoginBtn.style.display = '';
|
||||
@@ -1319,7 +1321,12 @@ function updateAccountUI() {
|
||||
return;
|
||||
}
|
||||
const tierLabel = authTier === 'personal' ? 'Personal' : 'Free';
|
||||
const fallbackName = (authEmail || 'User').split('@')[0] || 'User';
|
||||
const displayName = (authName || '').trim() || fallbackName;
|
||||
accountStatusEl.textContent = `Connected as ${authEmail || 'user'} (${tierLabel})`;
|
||||
if (accountGreetingEl) accountGreetingEl.textContent = `Hi, ${displayName}`;
|
||||
if (accountConnectFormEl) accountConnectFormEl.style.display = 'none';
|
||||
if (accountConnectedEl) accountConnectedEl.style.display = '';
|
||||
if (accountLoginBtn) {
|
||||
accountLoginBtn.disabled = true;
|
||||
accountLoginBtn.style.display = 'none';
|
||||
@@ -1535,6 +1542,7 @@ accountLoginBtn?.addEventListener('click', async () => {
|
||||
authApiKey = data?.api_key || '';
|
||||
authTier = String(data?.user?.tier || 'free');
|
||||
authEmail = String(data?.user?.email || email);
|
||||
authName = String(data?.user?.name || '');
|
||||
await saveSettings();
|
||||
updateAccountUI();
|
||||
setStatusTag();
|
||||
@@ -1566,6 +1574,7 @@ accountLogoutBtn?.addEventListener('click', async () => {
|
||||
} finally {
|
||||
authApiKey = '';
|
||||
authTier = 'guest';
|
||||
authName = '';
|
||||
await saveSettings();
|
||||
updateAccountUI();
|
||||
setStatusTag();
|
||||
@@ -1574,40 +1583,6 @@ accountLogoutBtn?.addEventListener('click', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
async function renderDiag(obj) {
|
||||
const lines = [];
|
||||
lines.push(`Content script loaded: ${obj ? 'yes' : 'no'}`);
|
||||
if (!obj) return lines.join('\n');
|
||||
|
||||
lines.push(`Active editable type: ${obj.activeType ?? 'none'}`);
|
||||
lines.push(`Has caret/selection: ${obj.hasRange ? 'yes' : 'no'}`);
|
||||
lines.push(`Last insert result: ${obj.lastInsertOK === null ? 'n/a' : obj.lastInsertOK ? 'success' : 'failed'}`);
|
||||
if (obj.lastInsertMessage) lines.push(`Note: ${obj.lastInsertMessage}`);
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
async function runDiagnostics() {
|
||||
diagOut.textContent = '';
|
||||
diagSpin.style.display = 'inline';
|
||||
|
||||
try {
|
||||
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
||||
if (!tab?.id) { diagOut.textContent = 'No active tab.'; return; }
|
||||
|
||||
const ready = await ensureContentScript(tab.id);
|
||||
if (!ready) { diagOut.textContent = await renderDiag(null); return; }
|
||||
|
||||
const info = await chrome.tabs.sendMessage(tab.id, { type: 'dewemoji_diag' });
|
||||
diagOut.textContent = await renderDiag(info || null);
|
||||
} catch (e) {
|
||||
diagOut.textContent = `Error: ${e?.message || e}`;
|
||||
} finally {
|
||||
diagSpin.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
diagRunBtn?.addEventListener('click', () => runDiagnostics());
|
||||
|
||||
async function performEmojiAction(glyph) {
|
||||
// Free users always copy
|
||||
const mode = licenseValid ? actionMode : 'copy';
|
||||
|
||||
Reference in New Issue
Block a user