Skip to content

Commit 443de87

Browse files
committed
refactor: improve basic popup view structure and fix issues (quoid#624)
cherry-pick from commits 821a649^..9d25daf
1 parent 1500e1b commit 443de87

5 files changed

Lines changed: 155 additions & 187 deletions

File tree

src/ext/action-popup/App.svelte

Lines changed: 127 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
let platform;
3030
let initError;
3131
let firstGuide;
32-
let windowHeight = 0;
3332
let header;
3433
let warn;
3534
let err;
@@ -42,13 +41,10 @@
4241
let installViewUserscriptError;
4342
let showAll;
4443
let allItems = [];
45-
let resizeTimer;
4644
let abort = false;
4745
4846
$: list = items.sort((a, b) => a.name.localeCompare(b.name));
4947
50-
$: if (platform) document.body.classList.add(platform);
51-
5248
function getItemBackgroundColor(elements, index) {
5349
if (elements.length < 2) return null;
5450
if (elements.length % 2 === 0 && index % 2 === 0) return "light";
@@ -259,9 +255,6 @@
259255
// set toggle state
260256
active = await settingsStorage.get("global_active");
261257
262-
// set popup height
263-
resize();
264-
265258
// get matches
266259
const currentTab = await browser.tabs.getCurrent();
267260
const url = currentTab.url;
@@ -361,35 +354,20 @@
361354
window.location.reload();
362355
}
363356
364-
async function resize() {
365-
if (!platform || platform === "macos") return;
366-
clearTimeout(resizeTimer);
367-
resizeTimer = setTimeout(async () => {
368-
if (platform === "ipados") {
369-
if (window.matchMedia("(max-width: 360px)").matches) {
370-
// the popup window is no greater than 360px
371-
// ensure body & main element have no leftover styling
372-
main.removeAttribute("style");
373-
document.body.removeAttribute("style");
374-
return;
375-
}
376-
main.style.maxHeight = "unset";
377-
document.body.style.width = "100vw";
378-
}
379-
// on ios and ipados (split view) programmatically set the height of the scrollable container
380-
// first get the header height
381-
const headerHeight = header.offsetHeight;
382-
// then check if a warning or error is visible (ie. taking up height)
383-
let addHeight = 0;
384-
// if warn or error elements visible, also subtract that from applied height
385-
if (warn) addHeight += warn.offsetHeight;
386-
if (err) addHeight += err.offsetHeight;
387-
windowHeight = window.outerHeight - (headerHeight + addHeight);
388-
main.style.height = `${windowHeight}px`;
389-
main.style.paddingBottom = `${headerHeight + addHeight}px`;
390-
}, 25);
391-
}
392-
357+
/** @type {import("svelte/elements").UIEventHandler<Window>} */
358+
// async function resizeHandler(event) {
359+
// if (platform !== "macos") {
360+
// const viewport = event.currentTarget.visualViewport;
361+
// console.debug(platform, viewport);
362+
// // add max limits after the window size has been rendered
363+
// // avoid display overflow when window shrinks dynamically
364+
// }
365+
// }
366+
367+
/**
368+
* Check if the current page contains a user script
369+
* @param {import("webextension-polyfill").Tabs.Tab} currentTab
370+
*/
393371
async function installCheck(currentTab) {
394372
// refetch script from URL to avoid tampered DOM content
395373
let res; // fetch response
@@ -472,8 +450,6 @@
472450
473451
onMount(async () => {
474452
await initialize();
475-
// run resize again for good measure
476-
resize();
477453
});
478454
479455
// handle native app messages
@@ -491,103 +467,6 @@
491467
}
492468
</script>
493469

494-
<svelte:window on:resize={resize} />
495-
<div class="header" bind:this={header}>
496-
<IconButton
497-
icon={iconOpen}
498-
title={"Open save location"}
499-
on:click={openSaveLocation}
500-
{disabled}
501-
/>
502-
<IconButton
503-
icon={iconUpdate}
504-
notification={!!updates.length}
505-
on:click={() => (showUpdates = true)}
506-
title={"Show updates"}
507-
{disabled}
508-
/>
509-
<IconButton
510-
icon={iconRefresh}
511-
on:click={refreshView}
512-
title={"Refresh view"}
513-
{disabled}
514-
/>
515-
<Toggle
516-
checked={active}
517-
title={"Toggle injection"}
518-
on:click={toggleExtension}
519-
{disabled}
520-
/>
521-
</div>
522-
{#if !active}
523-
<!-- <div class="warn" bind:this={warn}>Injection disabled</div> -->
524-
{/if}
525-
{#if showInstallPrompt}
526-
<div class="warn" class:done={scriptInstalled} bind:this={warn}>
527-
Userscript
528-
{#if scriptChecking}
529-
{showInstallPrompt}
530-
{:else}
531-
{scriptInstalled ? "Installed" : "Detected"}:
532-
<button on:click={showInstallView}>{showInstallPrompt}</button>
533-
{/if}
534-
</div>
535-
{/if}
536-
{#if errorNotification}
537-
<div class="error" bind:this={err}>
538-
{errorNotification}
539-
<IconButton
540-
icon={iconClear}
541-
on:click={() => (errorNotification = undefined)}
542-
title={"Clear error"}
543-
/>
544-
</div>
545-
{/if}
546-
<div class="main {rowColors || ''}" bind:this={main}>
547-
{#if loading}
548-
<Loader abortClick={abortUpdates} {abort} />
549-
{:else if inactive}
550-
<div class="none">Popup inactive on extension page</div>
551-
{:else if firstGuide}
552-
<div class="none">
553-
<p>Welcome, first use please:&nbsp;</p>
554-
<button class="link" on:click={openContainingApp}>
555-
Open Userscripts App
556-
</button>
557-
<p>to complete the initialization</p>
558-
</div>
559-
{:else if initError}
560-
<div class="none">
561-
Something went wrong:&nbsp;
562-
<button class="link" on:click={() => window.location.reload()}>
563-
click to retry
564-
</button>
565-
</div>
566-
{:else if items.length < 1}
567-
<div class="none">No matched userscripts</div>
568-
{:else}
569-
<div class="items" class:disabled>
570-
{#each list as item, i (item.filename)}
571-
<PopupItem
572-
background={getItemBackgroundColor(list, i)}
573-
enabled={!item.disabled}
574-
name={item.name}
575-
subframe={item.subframe}
576-
type={item.type}
577-
request={!!item.request}
578-
on:click={() => toggleItem(item)}
579-
/>
580-
{/each}
581-
</div>
582-
{/if}
583-
</div>
584-
{#if !inactive && platform === "macos"}
585-
<div class="footer">
586-
<button class="link" on:click={gotoExtensionPage}>
587-
Open Extension Page
588-
</button>
589-
</div>
590-
{/if}
591470
{#if showUpdates}
592471
<View
593472
headerTitle={"Updates"}
@@ -630,34 +509,140 @@
630509
>
631510
<AllItemsView {allItems} allItemsToggleItem={toggleItem} />
632511
</View>
512+
{:else}
513+
<div class="header" bind:this={header}>
514+
<div class="buttons">
515+
<IconButton
516+
icon={iconOpen}
517+
title={"Open save location"}
518+
on:click={openSaveLocation}
519+
{disabled}
520+
/>
521+
<IconButton
522+
icon={iconUpdate}
523+
notification={!!updates.length}
524+
on:click={() => (showUpdates = true)}
525+
title={"Show updates"}
526+
{disabled}
527+
/>
528+
<IconButton
529+
icon={iconRefresh}
530+
on:click={refreshView}
531+
title={"Refresh view"}
532+
{disabled}
533+
/>
534+
<Toggle
535+
checked={active}
536+
title={"Toggle injection"}
537+
on:click={toggleExtension}
538+
{disabled}
539+
/>
540+
</div>
541+
{#if !active}
542+
<!-- <div class="warn" bind:this={warn}>Injection disabled</div> -->
543+
{/if}
544+
{#if showInstallPrompt}
545+
<div class="warn" class:done={scriptInstalled} bind:this={warn}>
546+
Userscript
547+
{#if scriptChecking}
548+
{showInstallPrompt}
549+
{:else}
550+
{scriptInstalled ? "Installed" : "Detected"}:
551+
<button on:click={showInstallView}>{showInstallPrompt}</button>
552+
{/if}
553+
</div>
554+
{/if}
555+
{#if errorNotification}
556+
<div class="error" bind:this={err}>
557+
{errorNotification}
558+
<IconButton
559+
icon={iconClear}
560+
on:click={() => (errorNotification = undefined)}
561+
title={"Clear error"}
562+
/>
563+
</div>
564+
{/if}
565+
</div>
566+
<div class="main {rowColors || ''}" bind:this={main}>
567+
{#if loading}
568+
<Loader abortClick={abortUpdates} {abort} />
569+
{:else if inactive}
570+
<div class="none">Popup inactive on extension page</div>
571+
{:else if firstGuide}
572+
<div class="none">
573+
<p>Welcome, first use please:&nbsp;</p>
574+
<button class="link" on:click={openContainingApp}>
575+
Open Userscripts App
576+
</button>
577+
<p>to complete the initialization</p>
578+
</div>
579+
{:else if initError}
580+
<div class="none">
581+
Something went wrong:&nbsp;
582+
<button class="link" on:click={() => window.location.reload()}>
583+
click to retry
584+
</button>
585+
</div>
586+
{:else if items.length < 1}
587+
<div class="none">No matched userscripts</div>
588+
{:else}
589+
<div class="items" class:disabled>
590+
{#each list as item, i (item.filename)}
591+
<PopupItem
592+
background={getItemBackgroundColor(list, i)}
593+
enabled={!item.disabled}
594+
name={item.name}
595+
subframe={item.subframe}
596+
type={item.type}
597+
request={!!item.request}
598+
on:click={() => toggleItem(item)}
599+
/>
600+
{/each}
601+
</div>
602+
{/if}
603+
</div>
604+
{#if !inactive && platform === "macos"}
605+
<div class="footer">
606+
<button class="link" on:click={gotoExtensionPage}>
607+
Open Extension Page
608+
</button>
609+
</div>
610+
{/if}
633611
{/if}
634612

635613
<style>
636614
.header {
615+
background-color: var(--color-bg-secondary);
616+
position: sticky;
617+
top: 0;
618+
z-index: 1;
619+
}
620+
621+
.header .buttons {
637622
align-items: center;
638623
border-bottom: 1px solid var(--color-black);
639624
display: flex;
640625
padding: 0.5rem 1rem calc(0.5rem - 1px) 1rem;
641626
}
642627
643-
.header :global(button:nth-of-type(2)) {
628+
.header .buttons :global(button:nth-of-type(2)) {
644629
margin: 0 auto 0 1rem;
645630
}
646631
647-
.header :global(button:nth-of-type(3)) {
632+
.header .buttons :global(button:nth-of-type(3)) {
648633
margin-right: 1rem;
649634
}
650635
651-
.header :global(button:nth-of-type(1) svg) {
636+
.header .buttons :global(button:nth-of-type(1) svg) {
652637
transform: scale(0.75);
653638
}
654639
655-
.header :global(button:nth-of-type(2) svg) {
640+
.header .buttons :global(button:nth-of-type(2) svg) {
656641
transform: scale(0.9);
657642
}
658643
659-
.header :global(label) {
660-
font-size: 1.25rem !important;
644+
.header .buttons :global(button:nth-of-type(4)) {
645+
--toggle-font-size: 1.25rem;
661646
}
662647
663648
.error,
@@ -702,15 +687,12 @@
702687
}
703688
704689
.main {
690+
flex-grow: 1;
705691
min-height: 12.5rem;
706692
overflow-y: auto;
707693
position: relative;
708694
}
709695
710-
:global(body:not(.ios) .main) {
711-
max-height: 20rem;
712-
}
713-
714696
.none {
715697
font-weight: 600;
716698
color: var(--text-color-disabled);

src/ext/action-popup/Components/View.svelte

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,9 @@
3737

3838
<style>
3939
.view {
40-
background-color: var(--color-bg-primary);
40+
background-color: var(--color-bg-secondary);
4141
display: flex;
4242
flex-direction: column;
43-
height: 100%;
4443
left: 0;
4544
position: absolute;
4645
text-align: center;
@@ -50,16 +49,18 @@
5049
}
5150
5251
.view__header {
53-
background-color: var(--color-bg-primary);
52+
background-color: var(--color-bg-secondary);
5453
border-bottom: 1px solid var(--color-black);
5554
flex-shrink: 0;
5655
font-weight: 600;
5756
padding: 0.5rem 1rem calc(0.5rem - 1px) 1rem;
57+
position: sticky;
5858
top: 0;
59+
z-index: 5;
5960
}
6061
6162
.view :global(.loader) {
62-
background-color: var(--color-bg-primary);
63+
background-color: var(--color-bg-secondary);
6364
}
6465
6566
.view__header :global(button) {
@@ -70,7 +71,6 @@
7071
7172
.view__body {
7273
flex-grow: 1;
73-
overflow-y: auto;
7474
position: relative;
7575
}
7676
</style>

0 commit comments

Comments
 (0)