feat(browser-extension): improve ux/ui

This commit is contained in:
wanhose 2024-11-10 22:28:18 +01:00
parent 62b6a21b95
commit dc44a6f8da
3 changed files with 192 additions and 174 deletions

View File

@ -12,7 +12,11 @@
<header> <header>
<h1 class="header-title">Cookie Dialog Monster</h1> <h1 class="header-title">Cookie Dialog Monster</h1>
<div class="header-actions"> <div class="header-actions">
<button disabled id="report-button"> <button
class="header-button"
data-href="https://git.wanhose.dev/wanhose/cookie-dialog-monster/wiki/Help-or-issues%3F"
id="help-button"
>
<svg <svg
aria-hidden="true" aria-hidden="true"
fill="none" fill="none"
@ -24,11 +28,12 @@
viewBox="0 0 24 24" viewBox="0 0 24 24"
width="18" width="18"
> >
<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path> <circle cx="12" cy="12" r="10"></circle>
<line x1="4" y1="22" x2="4" y2="15"></line> <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
<line x1="12" y1="17" x2="12.01" y2="17"></line>
</svg> </svg>
</button> </button>
<button id="settings-button"> <button class="header-button" id="settings-button">
<svg <svg
aria-hidden="true" aria-hidden="true"
fill="none" fill="none"
@ -69,6 +74,29 @@
</svg> </svg>
</a> </a>
</p> </p>
<p aria-hidden="true" class="banner" data-variant="error" id="support-banner" role="alert">
<span data-i18n="popup_bannerSupport"></span>
<a
href="https://git.wanhose.dev/wanhose/cookie-dialog-monster/wiki/List-of-unsupported-sites"
target="_blank"
>
<svg
aria-hidden="true"
fill="none"
height="12"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
stroke="currentColor"
viewBox="0 0 24 24"
width="12"
>
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
<polyline points="15 3 21 3 21 9"></polyline>
<line x1="10" y1="14" x2="21" y2="3"></line>
</svg>
</a>
</p>
<p aria-hidden="true" class="banner" data-variant="notice" id="update-banner" role="alert"> <p aria-hidden="true" class="banner" data-variant="notice" id="update-banner" role="alert">
<span data-i18n="popup_bannerUpdateAvailable"></span> <span data-i18n="popup_bannerUpdateAvailable"></span>
<a <a
@ -94,7 +122,7 @@
</a> </a>
</p> </p>
<div class="content"> <div class="content">
<popup-button id="power-option" role="button" tabindex="0"> <button class="popup-button" disabled id="power-option">
<svg <svg
aria-hidden="true" aria-hidden="true"
fill="none" fill="none"
@ -110,13 +138,8 @@
<line x1="12" y1="2" x2="12" y2="12" /> <line x1="12" y1="2" x2="12" y2="12" />
</svg> </svg>
<span id="host"></span> <span id="host"></span>
</popup-button> </button>
<popup-button <button class="popup-button" disabled id="report-option" role="link">
data-href="https://git.wanhose.dev/wanhose/cookie-dialog-monster/wiki/Help-or-issues%3F"
id="help-option"
role="link"
tabindex="0"
>
<svg <svg
aria-hidden="true" aria-hidden="true"
fill="none" fill="none"
@ -128,17 +151,16 @@
viewBox="0 0 24 24" viewBox="0 0 24 24"
width="32" width="32"
> >
<path <path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path>
d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" <line x1="4" y1="22" x2="4" y2="15"></line>
/>
</svg> </svg>
<span data-i18n="popup_helpOption"></span> <span data-i18n="contextMenu_reportOption"></span>
</popup-button> </button>
<popup-button <button
class="popup-button"
data-href="https://git.wanhose.dev/wanhose/cookie-dialog-monster" data-href="https://git.wanhose.dev/wanhose/cookie-dialog-monster"
id="contribute-option" id="contribute-option"
role="link" role="link"
tabindex="0"
> >
<svg <svg
aria-hidden="true" aria-hidden="true"
@ -157,8 +179,8 @@
<line x1="6" y1="9" x2="6" y2="21"></line> <line x1="6" y1="9" x2="6" y2="21"></line>
</svg> </svg>
<span data-i18n="popup_contributeOption"></span> <span data-i18n="popup_contributeOption"></span>
</popup-button> </button>
<popup-button data-href="#" id="rate-option" role="link" tabindex="0"> <button class="popup-button" data-href="#" id="rate-option" role="link">
<svg <svg
aria-hidden="true" aria-hidden="true"
fill="none" fill="none"
@ -175,17 +197,12 @@
/> />
</svg> </svg>
<span data-i18n="popup_rateOption"></span> <span data-i18n="popup_rateOption"></span>
</popup-button> </button>
<popup-data-container> <div class="popup-data-container">
<popup-data> <div class="popup-data">
<b data-i18n="popup_databaseVersion"></b> <b data-i18n="popup_databaseVersion"></b>
<span id="database-version"></span> <span id="database-version"></span>
<popup-data-button <button class="popup-data-button" data-animation="flip" id="refresh-database-button">
data-animation="flip"
id="refresh-database-button"
role="button"
tabindex="0"
>
<svg <svg
aria-hidden="true" aria-hidden="true"
fill="none" fill="none"
@ -218,13 +235,13 @@
> >
<polyline points="20 6 9 17 4 12"></polyline> <polyline points="20 6 9 17 4 12"></polyline>
</svg> </svg>
</popup-data-button> </button>
</popup-data> </div>
<popup-data> <div class="popup-data">
<b data-i18n="popup_extensionVersion"></b> <b data-i18n="popup_extensionVersion"></b>
<span id="extension-version"></span> <span id="extension-version"></span>
</popup-data> </div>
</popup-data-container> </div>
</div> </div>
<div class="report" style="display: none"> <div class="report" style="display: none">
<div class="report-form-view"> <div class="report-form-view">
@ -290,12 +307,7 @@
</svg> </svg>
<div class="report-submit-text" data-i18n="report_submitErrorText"></div> <div class="report-submit-text" data-i18n="report_submitErrorText"></div>
<div class="report-submit-extra-text" data-i18n="report_submitErrorExtraText"></div> <div class="report-submit-extra-text" data-i18n="report_submitErrorExtraText"></div>
<div <div class="report-issue-button" data-i18n="contextMenu_issueOption"></div>
class="report-issue-button"
data-i18n="contextMenu_issueOption"
role="button"
tabindex="0"
></div>
</div> </div>
<div class="report-submit-success-view" hidden> <div class="report-submit-success-view" hidden>
<svg <svg
@ -314,12 +326,7 @@
</svg> </svg>
<div class="report-submit-text" data-i18n="report_submitSuccessText"></div> <div class="report-submit-text" data-i18n="report_submitSuccessText"></div>
<div class="report-submit-extra-text" data-i18n="report_submitSuccessExtraText"></div> <div class="report-submit-extra-text" data-i18n="report_submitSuccessExtraText"></div>
<div <div class="report-issue-button" data-i18n="contextMenu_issueOption"></div>
class="report-issue-button"
data-i18n="contextMenu_issueOption"
role="button"
tabindex="0"
></div>
</div> </div>
</div> </div>
</main> </main>

View File

@ -90,54 +90,10 @@ function handleCancelClick() {
*/ */
async function handleContentLoaded() { async function handleContentLoaded() {
const tab = await dispatch({ type: 'GET_TAB' }); const tab = await dispatch({ type: 'GET_TAB' });
const tabUrl = tab?.url ? new URL(tab.url) : undefined; const url = tab?.url ? new URL(tab.url) : undefined;
hostname = tabUrl?.hostname.split('.').slice(-3).join('.').replace('www.', ''); hostname = url?.hostname.split('.').slice(-3).join('.').replace('www.', '');
state = { ...((await dispatch({ hostname, type: 'GET_STATE' })) ?? state), tabId: tab?.id };
const next = await dispatch({ hostname, type: 'GET_STATE' });
state = { ...(next ?? state), tabId: tab?.id };
if (state.issue?.url) {
const issueBanner = document.getElementById('issue-banner');
issueBanner.removeAttribute('aria-hidden');
const issueBannerText = document.getElementById('issue-banner-text');
if (state.issue.flags.includes('wontfix'))
issueBannerText.innerText = browser.i18n.getMessage('popup_bannerIssueWontFix');
else issueBannerText.innerText = browser.i18n.getMessage('popup_bannerIssueOpen');
const issueBannerUrl = document.getElementById('issue-banner-url');
issueBannerUrl.setAttribute('href', state.issue.url);
} else {
const cancelButtonElement = document.getElementsByClassName('report-cancel-button')[0];
cancelButtonElement?.addEventListener('click', handleCancelClick);
const reasonInputElement = document.getElementById('report-input-reason');
reasonInputElement?.addEventListener('input', handleInputChange);
reasonInputElement?.addEventListener('keydown', handleInputKeyDown);
if (!state.updateAvailable) {
const reportButtonElement = document.getElementById('report-button');
reportButtonElement?.addEventListener('click', handleReportClick);
reportButtonElement?.removeAttribute('disabled');
}
const urlInputElement = document.getElementById('report-input-url');
urlInputElement?.addEventListener('input', handleInputChange);
urlInputElement?.addEventListener('keydown', handleInputKeyDown);
if (tabUrl) urlInputElement?.setAttribute('value', `${tabUrl.origin}${tabUrl.pathname}`);
const submitButtonElement = document.getElementsByClassName('report-submit-button')[0];
submitButtonElement?.addEventListener('click', handleSubmitButtonClick);
}
if (state.updateAvailable) {
const updateBanner = document.getElementById('update-banner');
updateBanner.removeAttribute('aria-hidden');
const updateBannerUrl = document.getElementById('update-banner-url');
updateBannerUrl.href += `/tag/${state.updateAvailable}`;
}
const hostTextElement = document.getElementById('host'); const hostTextElement = document.getElementById('host');
hostTextElement.innerText = hostname ?? 'unknown'; hostTextElement.innerText = hostname ?? 'unknown';
@ -151,14 +107,9 @@ async function handleContentLoaded() {
const extensionVersionElement = document.getElementById('extension-version'); const extensionVersionElement = document.getElementById('extension-version');
extensionVersionElement.innerText = browser.runtime.getManifest().version; extensionVersionElement.innerText = browser.runtime.getManifest().version;
const helpButtonElement = document.getElementById('help-option'); const helpButtonElement = document.getElementById('help-button');
helpButtonElement?.addEventListener('click', handleLinkRedirect); helpButtonElement?.addEventListener('click', handleLinkRedirect);
const powerButtonElement = document.getElementById('power-option');
powerButtonElement?.addEventListener('click', handlePowerToggle);
if (state.on) powerButtonElement?.setAttribute('data-value', 'on');
else powerButtonElement?.setAttribute('data-value', 'off');
const rateButtonElement = document.getElementById('rate-option'); const rateButtonElement = document.getElementById('rate-option');
rateButtonElement?.addEventListener('click', handleLinkRedirect); rateButtonElement?.addEventListener('click', handleLinkRedirect);
if (isEdge) rateButtonElement?.setAttribute('data-href', edgeUrl); if (isEdge) rateButtonElement?.setAttribute('data-href', edgeUrl);
@ -170,6 +121,62 @@ async function handleContentLoaded() {
translate(); translate();
await updateDatabaseVersion(); await updateDatabaseVersion();
const { exclusions } = (await dispatch({ hostname, type: 'GET_DATA' })) ?? {};
if (exclusions?.domains.some((x) => url.hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) {
const supportBanner = document.getElementById('support-banner');
supportBanner.removeAttribute('aria-hidden');
return;
}
if (state.issue?.url) {
const issueBanner = document.getElementById('issue-banner');
issueBanner.removeAttribute('aria-hidden');
const issueBannerText = document.getElementById('issue-banner-text');
if (state.issue.flags.includes('wontfix'))
issueBannerText.innerText = browser.i18n.getMessage('popup_bannerIssueWontFix');
else issueBannerText.innerText = browser.i18n.getMessage('popup_bannerIssueOpen');
const issueBannerUrl = document.getElementById('issue-banner-url');
issueBannerUrl.setAttribute('href', state.issue.url);
return;
}
if (state.updateAvailable) {
const updateBanner = document.getElementById('update-banner');
updateBanner.removeAttribute('aria-hidden');
const updateBannerUrl = document.getElementById('update-banner-url');
updateBannerUrl.href += `/tag/${state.updateAvailable}`;
return;
}
const cancelButtonElement = document.getElementsByClassName('report-cancel-button')[0];
cancelButtonElement?.addEventListener('click', handleCancelClick);
const powerButtonElement = document.getElementById('power-option');
powerButtonElement?.addEventListener('click', handlePowerToggle);
powerButtonElement?.removeAttribute('disabled');
if (state.on) powerButtonElement?.setAttribute('data-value', 'on');
else powerButtonElement?.setAttribute('data-value', 'off');
const reasonInputElement = document.getElementById('report-input-reason');
reasonInputElement?.addEventListener('input', handleInputChange);
reasonInputElement?.addEventListener('keydown', handleInputKeyDown);
const reportButtonElement = document.getElementById('report-option');
reportButtonElement?.addEventListener('click', handleReportClick);
reportButtonElement?.removeAttribute('disabled');
const submitButtonElement = document.getElementsByClassName('report-submit-button')[0];
submitButtonElement?.addEventListener('click', handleSubmitButtonClick);
const urlInputElement = document.getElementById('report-input-url');
urlInputElement?.addEventListener('input', handleInputChange);
urlInputElement?.addEventListener('keydown', handleInputKeyDown);
if (url) urlInputElement?.setAttribute('value', `${url.origin}${url.pathname}`);
} }
/** /**

View File

@ -8,6 +8,10 @@
--color-white: #ffffff; --color-white: #ffffff;
} }
b {
font-weight: bold;
}
body { body {
box-sizing: border-box; box-sizing: border-box;
color: var(--color-tertiary); color: var(--color-tertiary);
@ -26,30 +30,6 @@ body * {
font-family: Inter, Arial, Helvetica, sans-serif; font-family: Inter, Arial, Helvetica, sans-serif;
} }
button {
align-items: center;
background-color: var(--color-secondary);
border: none;
border-radius: 4px;
color: var(--color-white);
display: inline-flex;
gap: 4px;
outline: none;
padding: 2px;
transition: 0.4s;
&:focus:not(:disabled),
&:hover:not(:disabled) {
background-color: var(--color-white);
color: var(--color-secondary);
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
footer { footer {
background-color: var(--color-secondary); background-color: var(--color-secondary);
flex-shrink: 0; flex-shrink: 0;
@ -73,11 +53,6 @@ header {
& .header-actions { & .header-actions {
display: flex; display: flex;
gap: 8px; gap: 8px;
& #report-button:focus:not(:disabled) > svg,
& #report-button:hover:not(:disabled) > svg {
color: var(--color-error);
}
} }
} }
@ -99,6 +74,11 @@ main > .banner {
display: none; display: none;
} }
&[data-variant='error'] {
background-color: #e74c3c;
color: var(--color-white);
}
&[data-variant='notice'] { &[data-variant='notice'] {
background-color: #2196f3; background-color: #2196f3;
color: var(--color-white); color: var(--color-white);
@ -109,8 +89,7 @@ main > .banner {
color: #c0392b; color: #c0392b;
} }
& #issue-banner-url, & a {
& #update-banner-url {
color: inherit; color: inherit;
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
@ -124,8 +103,28 @@ main > .content {
padding: 16px; padding: 16px;
} }
popup-button { .header-button {
align-items: center;
background-color: var(--color-secondary);
border: none;
border-radius: 4px; border-radius: 4px;
color: var(--color-white);
display: inline-flex;
gap: 4px;
outline: none;
padding: 2px;
transition: 0.4s;
&:focus:not(:disabled),
&:hover:not(:disabled) {
background-color: var(--color-white);
color: var(--color-secondary);
}
}
.popup-button {
border-radius: 4px;
color: var(--color-secondary);
cursor: pointer; cursor: pointer;
display: grid; display: grid;
font-size: 14px; font-size: 14px;
@ -140,53 +139,62 @@ popup-button {
transition: 0.4s; transition: 0.4s;
width: 100%; width: 100%;
word-break: break-word; word-break: break-word;
}
popup-button:focus, &:focus,
popup-button:hover { &:hover {
box-shadow: box-shadow:
rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(50, 50, 93, 0.25) 0px 2px 5px -1px,
rgba(0, 0, 0, 0.3) 0px 1px 3px -1px; rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
} }
popup-button > span { &:disabled {
background-color: var(--color-tertiary);
box-shadow: none;
color: var(--color-white);
cursor: not-allowed;
opacity: 0.5;
}
& span {
align-self: flex-start; align-self: flex-start;
} }
popup-button > svg { & svg {
align-self: flex-end; align-self: flex-end;
}
} }
popup-data { .popup-data {
align-items: center; align-items: center;
display: flex; display: flex;
gap: 4px; gap: 4px;
justify-content: center; justify-content: center;
outline: none; outline: none;
}
popup-data:not(:first-child) { &:not(:first-child) {
margin-top: 4px; margin-top: 4px;
}
} }
popup-data-button { .popup-data-button {
color: var(--color-tertiary);
cursor: pointer; cursor: pointer;
line-height: 0; line-height: 0;
outline: none; outline: none;
transition: 0.4s; transition: 0.4s;
}
popup-data-button[aria-disabled='true'] { &[aria-disabled='true'] {
cursor: not-allowed; cursor: not-allowed;
} }
popup-data-button[data-animation='flip']:focus, &[data-animation='flip']:focus,
popup-data-button[data-animation='flip']:hover { &[data-animation='flip']:hover {
transform: rotate(-180deg); transform: rotate(-180deg);
} }
popup-data-button[data-refreshing='true'] { &[data-refreshing='true'] {
animation: spin 1s linear infinite; animation: spin 1s linear infinite;
}
} }
@keyframes spin { @keyframes spin {
@ -195,7 +203,7 @@ popup-data-button[data-refreshing='true'] {
} }
} }
popup-data-container { .popup-data-container {
font-size: 12px; font-size: 12px;
grid-column: 1 / -1; grid-column: 1 / -1;
justify-self: center; justify-self: center;
@ -396,10 +404,6 @@ popup-data-container {
} }
} }
b {
font-weight: bold;
}
#refresh-database-check { #refresh-database-check {
display: none; display: none;
} }
@ -407,14 +411,14 @@ b {
#power-option { #power-option {
color: var(--color-white); color: var(--color-white);
word-break: break-all; word-break: break-all;
}
#power-option[data-value='off'] { &[data-value='off'] {
background-color: var(--color-error); background-color: var(--color-error);
} }
#power-option[data-value='on'] { &[data-value='on'] {
background-color: var(--color-success); background-color: var(--color-success);
}
} }
#rate-option > svg { #rate-option > svg {