Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(popup): userscript detail view #447

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
3 changes: 1 addition & 2 deletions src/page/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import "./cm.css";

if (import.meta.env.DEV) { // vite feat that only import in dev mode
const modules = import.meta.glob("../shared/dev.js", {eager: true});
// eslint-disable-next-line no-global-assign
browser = modules["../shared/dev.js"].browser;
window.browser = modules["../shared/dev.js"].browser;
console.info("DEV-ENV", import.meta.env, modules, browser);
}

Expand Down
84 changes: 59 additions & 25 deletions src/popup/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import PopupItem from "./Components/PopupItem.svelte";
import View from "./Components/View.svelte";
import UpdateView from "./Components/Views/UpdateView.svelte";
import InstallView from "./Components/Views/InstallView.svelte";
import DetailView from "./Components/Views/DetailView.svelte";
import AllItemsView from "./Components/Views/AllItemsView.svelte";
import iconOpen from "../shared/img/icon-open.svg?raw";
import iconUpdate from "../shared/img/icon-update.svg?raw";
Expand All @@ -31,13 +31,13 @@
let header;
let warn;
let err;
let currentTabItem;
let scriptChecking;
let scriptInstalled;
let showInstallPrompt;
let showInstall;
let installUserscript; // url, content
let installViewUserscript; // metadata
let installViewUserscriptError;
let showDetailView;
let detailViewTitle;
let detailViewItem;
let showAll;
let allItems = [];
let resizeTimer;
Expand Down Expand Up @@ -123,6 +123,12 @@
});
}

function detailItem(item) {
detailViewItem = item;
detailViewTitle = "Userscript Detail";
showDetailView = true;
}

function checkForUpdates() {
disabled = true;
initError = false;
Expand Down Expand Up @@ -403,28 +409,30 @@
}
const content = await res.text();
// caching script data
installUserscript = {url: currentTab.url, content};
currentTabItem = {url: currentTab.url, content};
// send native swift a message, parse metadata and check if installed
const response = await browser.runtime.sendNativeMessage({name: "POPUP_INSTALL_CHECK", content});
console.info("POPUP_INSTALL_CHECK:", response);
if (response.error) {
console.error(`Error checking .user.js url: ${response.error}`);
// errorNotification = response.error;
installViewUserscriptError = response.error;
currentTabItem.error = response.error;
} else {
scriptInstalled = response.installed;
// caching script metadata
installViewUserscript = response.metadata;
currentTabItem.installed = response.installed;
currentTabItem.metadata = response.metadata;
// the response will contain the string to display
// ex: {success: "Click to install"}
showInstallPrompt = response.success;
}
scriptChecking = false;
}

async function showInstallView() {
async function installItem() {
detailViewItem = currentTabItem;
detailViewTitle = "Install Userscript";
// show the install view
showInstall = true;
showDetailView = true;
}

async function installConfirm() {
Expand All @@ -436,13 +444,13 @@
// show loading element
loading = true;
// go back to main view
showInstall = false;
showDetailView = false;
// double check before send install message
if (!installUserscript || !installUserscript.content) {
if (!currentTabItem) {
errorNotification = "Install failed: userscript missing";
}
const currentTab = await browser.tabs.getCurrent();
if (currentTab.url !== installUserscript.url) {
if (currentTab.url !== currentTabItem.url) {
errorNotification = "Install failed: tab changed unexpectedly";
}
if (errorNotification) {
Expand All @@ -453,7 +461,7 @@
// send native swift a message, which will start the install process
const response = await browser.runtime.sendNativeMessage({
name: "POPUP_INSTALL_SCRIPT",
content: installUserscript.content
content: currentTabItem.content
});
if (response.error) {
errorNotification = response.error;
Expand All @@ -466,6 +474,29 @@
refreshView();
}

async function updateConfirm() {
console.log("updateConfirm");
// TODO
// will be implement after the new async update check is implemented
}

async function trashConfirm() {
disabled = true;
const message = {name: "POPUP_TRASH", item: detailViewItem};
const response = await browser.runtime.sendNativeMessage(message);
if (response.error) {
errorNotification = response.error;
} else {
// delete the item in the cache array after success
allItems = allItems.filter(obj => obj.filename !== detailViewItem.filename);
// refresh main view
refreshView();
}
disabled = false;
// exit detail view
showDetailView = undefined;
}

onMount(async () => {
await initialize();
// run resize again for good measure
Expand Down Expand Up @@ -520,7 +551,7 @@
{showInstallPrompt}
{:else}
{scriptInstalled ? "Installed" : "Detected"}:
<span on:click={showInstallView}>{showInstallPrompt}</span>
<span on:click={installItem}>{showInstallPrompt}</span>
{/if}
</div>
{/if}
Expand Down Expand Up @@ -562,7 +593,8 @@
subframe={item.subframe}
type={item.type}
request={!!item.request}
on:click={() => toggleItem(item)}
toggleItem={() => toggleItem(item)}
detailItem={() => detailItem(item)}
/>
{/each}
</div>
Expand Down Expand Up @@ -592,18 +624,19 @@
{updates}
/>
</View>
{:else if showInstall}
{:else if showDetailView}
<View
headerTitle={"Install Userscript"}
headerTitle={detailViewTitle}
loading={disabled}
closeClick={() => showInstall = false}
closeClick={() => showDetailView = false}
showLoaderOnDisabled={true}
>
<InstallView
userscript={installViewUserscript}
installError={installViewUserscriptError}
installCancelClick={() => showInstall = false}
<DetailView
itemdata={detailViewItem}
goBackClick={() => showDetailView = false}
installConfirmClick={installConfirm}
updateConfirmClick={updateConfirm}
trashConfirmClick={trashConfirm}
/>
</View>
{:else if showAll}
Expand All @@ -618,7 +651,8 @@
>
<AllItemsView
allItems={allItems}
allItemsToggleItem={toggleItem}
toggleItem={toggleItem}
detailItem={detailItem}
/>
</View>
{/if}
Expand Down
57 changes: 50 additions & 7 deletions src/popup/Components/PopupItem.svelte
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
<script>
import IconButton from "../../shared/Components/IconButton.svelte";
import Tag from "../../shared/Components/Tag.svelte";
import iconInfo from "../../shared/img/icon-info.svg?raw";

export let background;
export let enabled = false;
export let name;
export let type;
export let subframe;
export let request = false;
export let toggleItem;
export let detailItem;
</script>

<div
class="item {enabled ? "enabled" : "disabled"} {background ?? ""}"
on:click
>
<span></span>
<div class="truncate">{name}</div>
{#if subframe}<div class="subframe">SUB</div>{/if}
<Tag type={request ? "request" : type}/>
<div class="base" on:click={toggleItem}>
<Tag type={request ? "request" : type}/>
<span></span>
<div class="truncate">{name}</div>
{#if subframe}<div class="subframe">SUB</div>{/if}
</div>
<div class="more" on:click={detailItem}>
<IconButton
icon={iconInfo}
title="Show user script details"
ACTCD marked this conversation as resolved.
Show resolved Hide resolved
/>
</div>
</div>

<style>
.item {
align-items: center;
cursor: pointer;
display: flex;
padding: 0.5rem 1rem;
position: relative;
-webkit-user-select: none;
user-select: none;
Expand All @@ -38,10 +49,42 @@
.item:hover {
background-color: rgb(255 255 255 / 0.075);
}

.item:active {
background-color: rgb(255 255 255 / 0.15);
}
}

.item:active {
background-color: rgb(255 255 255 / 0.15);
.item .base {
align-items: center;
cursor: pointer;
display: flex;
flex-grow: 1;
overflow: hidden;
padding: .5rem 0 .5rem .75rem;
position: relative;
-webkit-user-select: none;
user-select: none;
}

.item .more {
padding: .5rem;
font-weight: bold;
}

.more :global(button svg) {
opacity: 1;
transform: scale(0.75);
}

@media (hover: hover) {
.more :global(button svg:not(:hover)) {
opacity: 0.25;
}

.more:hover :global(button svg) {
opacity: 1;
}
}

span {
Expand Down
6 changes: 4 additions & 2 deletions src/popup/Components/Views/AllItemsView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import PopupItem from "../PopupItem.svelte";

export let allItems = [];
export let allItemsToggleItem;
export let toggleItem;
export let detailItem;

let disabled;
let rowColorsAll;
Expand All @@ -27,7 +28,8 @@
subframe={item.subframe}
type={item.type}
request={!!item.request}
on:click={() => allItemsToggleItem(item)}
toggleItem={() => toggleItem(item)}
detailItem={() => detailItem(item)}
/>
{/each}
</div>
Expand Down
Loading