diff options
Diffstat (limited to 'extension/src')
22 files changed, 375 insertions, 473 deletions
diff --git a/extension/src/assets/all.scss b/extension/src/assets/all.scss new file mode 100644 index 0000000..ede0b30 --- /dev/null +++ b/extension/src/assets/all.scss @@ -0,0 +1,14 @@ +@tailwind base; + +@tailwind components; + +@tailwind utilities; + +@import "./buttons.scss"; +@import "./footer.scss"; +@import "./header.scss"; +@import "./inputs.scss"; +@import "./headings.scss"; +@import "./toast.scss"; +@import "./etc.scss"; +@import "./modals.scss";
\ No newline at end of file diff --git a/extension/src/assets/buttons.scss b/extension/src/assets/buttons.scss new file mode 100644 index 0000000..325c60c --- /dev/null +++ b/extension/src/assets/buttons.scss @@ -0,0 +1,44 @@ +.button-group { + @apply inline-flex -space-x-0 divide-x overflow-hidden rounded-lg border border-transparent shadow-sm; + @apply divide-gray-300 border-gray-300 dark:divide-dark-500 dark:border-dark-500; + + & .btn { + @apply border-0 ring-0 focus:ring-0; + } +} + +.btn { + @apply ease-in-out duration-100 border px-4 py-2 text-center text-sm font-medium transition-all focus:ring; + @apply bg-white border-gray-300 text-gray-700 shadow-sm hover:bg-gray-100 focus:ring-gray-100; + + .dark & { + @apply bg-transparent text-inherit border-dark-300 hover:bg-transparent hover:border-gray-400 focus:ring-gray-300; + } + + &.borderless, + &.no-border, + &.b-0{ + @apply bg-transparent border-0 shadow-none ring-0 focus:ring-0 active:ring-0; + } + + &:disabled { + @apply cursor-not-allowed border-gray-100 bg-gray-50 text-gray-400; + @apply dark:bg-transparent dark:border-dark-400 dark:text-dark-300; + } + + &.sm { + @apply px-3 py-1.5 text-sm; + } + + &.xs { + @apply px-2 py-1; + } + + &.lg { + @apply px-5 py-3 text-lg; + } + + &.xl { + @apply px-6 py-4 text-xl; + } +} diff --git a/extension/src/assets/etc.scss b/extension/src/assets/etc.scss new file mode 100644 index 0000000..5675fbd --- /dev/null +++ b/extension/src/assets/etc.scss @@ -0,0 +1,25 @@ +.vue-notification-group.general-toast { + @apply right-5; +} + +.float-label { + @apply mt-5 relative; + + &>label { + @apply absolute top-0 left-0 bottom-0 block pl-3 ease-linear duration-75 opacity-0; + } + + &>input:focus+label { + @apply opacity-100 -mt-6; + } +} + +.default-page-template { + min-height: 400px; + @apply container w-full max-w-4xl px-4 pt-3 mx-auto sm:pt-6 md:px-0; +} + +a.link { + @apply duration-150 ease-in-out; + @apply text-primary-500 hover:text-primary-600; +}
\ No newline at end of file diff --git a/extension/src/assets/footer.scss b/extension/src/assets/footer.scss new file mode 100644 index 0000000..10f0076 --- /dev/null +++ b/extension/src/assets/footer.scss @@ -0,0 +1,3 @@ +footer{ + +}
\ No newline at end of file diff --git a/extension/src/assets/header.scss b/extension/src/assets/header.scss new file mode 100644 index 0000000..62e6b4f --- /dev/null +++ b/extension/src/assets/header.scss @@ -0,0 +1,3 @@ +header{ + +}
\ No newline at end of file diff --git a/extension/src/assets/headings.scss b/extension/src/assets/headings.scss new file mode 100644 index 0000000..fe9b039 --- /dev/null +++ b/extension/src/assets/headings.scss @@ -0,0 +1,32 @@ +h1, +h2, +h3, +h4, +h5, +h6 { + @apply font-medium leading-tight mt-0 mb-2; +} + +h1 { + @apply sm:text-4xl text-3xl; +} + +h2 { + @apply sm:text-3xl text-2xl; +} + +h3 { + @apply sm:text-2xl text-xl; +} + +h4 { + @apply sm:text-xl text-lg; +} + +h5 { + @apply sm:text-lg text-base; +} + +h6 { + @apply sm:text-base text-sm; +}
\ No newline at end of file diff --git a/extension/src/assets/inputs.scss b/extension/src/assets/inputs.scss new file mode 100644 index 0000000..62d03d4 --- /dev/null +++ b/extension/src/assets/inputs.scss @@ -0,0 +1,71 @@ +input.input, +select.input, +textarea.input { + @apply duration-100 ease-in-out outline-none border px-2 py-1.5; + @apply border-gray-200 bg-inherit dark:border-dark-400 dark:text-white hover:border-gray-300 hover:dark:border-dark-200; +} + + +/* CHECKBOXES */ + +label.checkbox { + @apply flex items-center cursor-pointer; + + input[type="checkbox"] { + @apply ease-in-out duration-100 w-5 h-5; + @apply border-2 rounded-sm border-gray-300 dark:border-dark-500; + + &:checked { + @apply text-primary-500 dark:text-primary-600 border-primary-500 dark:border-primary-600; + } + } + + &.primary { + input[type="checkbox"] { + @apply appearance-none; + @apply hover:border-primary-500 dark:hover:border-primary-600; + + &:checked { + @apply bg-primary-500 dark:bg-primary-600 border-primary-500 dark:border-primary-600; + } + + &+span.check { + clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); + @apply bg-white dark:bg-dark-500; + } + } + + span.check { + margin: 0px 0px 1px 4px; + @apply absolute h-3 w-3; + } + } + +} + +/*Select */ +select.input { + option { + @apply dark:bg-dark-700 ; + } +} + +select.input.options { + @apply text-current; +} + +select.input:disabled{ + @apply appearance-none; +} + +/*Validation inputs*/ +input.input.dirty.data-valid, +select.input.dirty.data-valid { + @apply border-primary-500 dark:border-primary-600; +} + +input.input.dirty.data-invalid, +select.input.dirty.data-invalid { + @apply border-red-600 dark:border-red-500; +} + diff --git a/extension/src/assets/modals.scss b/extension/src/assets/modals.scss new file mode 100644 index 0000000..254b8e1 --- /dev/null +++ b/extension/src/assets/modals.scss @@ -0,0 +1,29 @@ +.modal-entry { + background: #00000077; + @apply fixed z-50 flex w-full px-6; + + .modal-content-container { + @apply w-full max-w-md p-5 m-auto rounded-md shadow-2xl mt-44; + @apply bg-white border border-transparent dark:bg-dark-600 dark:border-primary-500 dark:text-white; + + .modal-title { + @apply text-xl font-bold; + } + + .modal-description { + @apply text-sm; + } + } + + .modal-button-container { + @apply flex flex-row justify-end pt-3 gap-3; + } + + .input-container { + @apply pt-5; + + input { + @apply w-full; + } + } +}
\ No newline at end of file diff --git a/extension/src/assets/tailwind.scss b/extension/src/assets/tailwind.scss deleted file mode 100644 index 7d1b1f6..0000000 --- a/extension/src/assets/tailwind.scss +++ /dev/null @@ -1,354 +0,0 @@ -@tailwind base; - -@tailwind components; - -@tailwind utilities; - -#injected-root { - - /* HEADINGS */ - h1, h2, h3, h4, h5, h6{ - @apply font-medium leading-tight mt-0 mb-2; - } - h1{ - @apply sm:text-5xl text-4xl; - } - h2{ - @apply sm:text-4xl text-3xl; - } - h3{ - @apply sm:text-3xl text-2xl; - } - h4{ - @apply sm:text-2xl text-xl; - } - h5{ - @apply sm:text-xl text-lg; - } - h6{ - @apply sm:text-base text-sm; - } - - - input.primary, - select.primary, - textarea.primary { - @apply border-2 rounded-md p-2 py-1.5 border-gray-200; - @apply dark:bg-dark-800 dark:border-dark-400 dark:text-white; - - &:focus, - &::after, - &:active{ - @apply outline-none border-primary-500 dark:border-primary-600; - } - - &.error, - &.error:focus, - &.error::after, - &.error:active{ - @apply outline-none border-red-500 dark:border-red-400; - } - } - - /* CHECKBOXES */ - - label.checkbox{ - @apply flex items-center cursor-pointer; - - input[type="checkbox"] { - @apply ease-in-out duration-100 w-5 h-5; - @apply border-2 rounded-sm border-gray-300 dark:border-dark-500; - - &:checked { - @apply text-primary-500 dark:text-primary-600 border-primary-500 dark:border-primary-600; - } - } - - &.primary { - input[type="checkbox"]{ - @apply appearance-none; - @apply hover:border-primary-500 dark:hover:border-primary-600; - - &:checked { - @apply bg-primary-500 dark:bg-primary-600 border-primary-500 dark:border-primary-600; - } - - & + span.check{ - clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); - @apply bg-white dark:bg-dark-500; - } - } - - span.check{ - margin: 0px 0px 1px 4px; - @apply absolute h-3 w-3; - } - } - - } - - /*Select */ - - select.primary.options{ - @apply text-current; - } - - - /*Validation inputs*/ - - input.primary.dirty.data-valid, - select.primary.dirty.data-valid - { - @apply border-primary-500 dark:border-primary-600; - } - input.primary.dirty.data-invalid, - select.primary.dirty.data-invalid - { - @apply border-red-600 dark:border-red-500; - } - - - input, - input:hover, - input:focus, - input:active, - input::after { - @apply duration-100 ease-in-out outline-none; - } - - .default-page-template { - min-height: 400px; - @apply container w-full max-w-4xl px-4 pt-3 mx-auto sm:pt-6 md:px-0; - } - - #header-mobile-nav a:hover, - #header-desktop-nav a:hover, - #header-mobile-nav .router-link-active, - #header-desktop-nav .router-link-active, - footer .footer-content .router-link-active { - @apply text-primary-500 dark:text-primary-600; - } - - #header-mobile-nav a { - @apply text-xl; - } - - a.link { - @apply duration-150 ease-in-out; - @apply text-purple-500 hover:text-purple-600; - } - - .modal-entry { - background: #00000077; - @apply fixed z-50 flex w-full; - - .modal-content-container { - @apply w-full max-w-md p-5 m-auto rounded-md shadow-2xl md:mt-44 mt-28; - @apply bg-white border border-transparent dark:bg-dark-600 dark:border-primary-500 dark:text-white; - - .modal-title { - @apply text-xl font-bold; - } - - .modal-description { - @apply text-sm; - } - } - - .modal-button-container { - @apply flex flex-row justify-end pt-3 gap-3; - } - - .input-container { - @apply pt-5; - - input { - @apply w-full; - } - } - } - - .btn { - @apply ease-in-out duration-100 border border-transparent px-4 py-2 text-center text-sm font-medium transition-all focus:ring-2; - - @apply bg-white border-gray-300 text-gray-700 shadow-sm hover:bg-gray-100 focus:ring-gray-100; - - .dark & { - @apply bg-transparent text-inherit border-dark-300 hover:bg-transparent hover:border-gray-400 focus:ring-gray-300; - } - - &.b-0 { - @apply border-0 ring-0; - } - - &:disabled { - @apply cursor-not-allowed border-gray-100 bg-gray-50 text-gray-400; - @apply dark:bg-transparent dark:border-dark-400 dark:text-dark-300; - } - - &.sm { - @apply px-3 py-1.5 text-sm; - } - - &.xs { - @apply px-2 py-1; - } - - &.primary { - @apply border-primary-500 bg-primary-500 text-white hover:border-primary-600 hover:bg-primary-600 focus:ring-primary-200; - - &:disabled { - @apply bg-primary-300 border-primary-300; - @apply dark:bg-transparent dark:border-primary-400; - } - - .dark & { - @apply border-primary-600 bg-transparent text-primary-600 hover:border-primary-500 hover:text-primary-500 focus:ring-primary-500; - } - } - - &.secondary { - @apply border-secondary-500 bg-secondary-500 text-white hover:border-secondary-600 hover:bg-secondary-600 focus:ring-secondary-200; - - &:disabled { - @apply bg-secondary-300 border-secondary-300; - @apply dark:bg-transparent dark:border-secondary-400; - } - - .dark & { - @apply border-secondary-600 bg-transparent text-secondary-600 hover:border-secondary-500 hover:text-secondary-500 focus:ring-secondary-500; - } - } - - &.red { - @apply border-red-500 bg-red-500 text-white hover:border-red-600 hover:bg-red-600 focus:ring-red-200; - - &:disabled { - @apply bg-red-300 border-red-300; - @apply dark:bg-transparent dark:border-red-400; - } - - .dark & { - @apply border-red-600 bg-transparent text-red-600 hover:border-red-500 hover:text-red-500 focus:ring-red-500; - } - } - - &.blue { - @apply border-blue-500 bg-blue-500 text-white hover:border-blue-600 hover:bg-blue-600 focus:ring-blue-200; - - &:disabled { - @apply bg-blue-300 border-blue-300; - @apply dark:bg-transparent dark:border-blue-400; - } - - .dark & { - @apply border-blue-600 bg-transparent text-blue-600 hover:border-blue-500 hover:text-blue-500 focus:ring-blue-500; - } - } - - &.green { - @apply border-green-500 bg-green-500 text-white hover:border-green-600 hover:bg-green-600 focus:ring-green-200; - - &:disabled { - @apply bg-green-300 border-green-300; - @apply dark:bg-transparent dark:border-green-400; - } - - .dark & { - @apply border-green-600 bg-transparent text-green-600 hover:border-green-500 hover:text-green-500 focus:ring-green-500; - } - } - - &.yellow { - @apply border-yellow-500 bg-yellow-500 text-white hover:border-yellow-600 hover:bg-yellow-600 focus:ring-yellow-200; - - &:disabled { - @apply bg-yellow-300 border-yellow-300; - @apply dark:bg-transparent dark:border-yellow-400; - } - - .dark & { - @apply border-yellow-400 bg-transparent text-yellow-400 hover:border-yellow-300 hover:text-yellow-300 focus:ring-yellow-300; - } - } - - &.purple { - @apply border-purple-500 bg-purple-500 text-white hover:border-purple-600 hover:bg-purple-600 focus:ring-purple-200; - - &:disabled { - @apply bg-purple-300 border-purple-300; - @apply dark:bg-transparent dark:border-purple-400; - } - - .dark & { - @apply border-purple-600 bg-transparent text-purple-600 hover:border-purple-500 hover:text-purple-500 focus:ring-purple-500; - } - } - - &.pink { - @apply border-pink-500 bg-pink-500 text-white hover:border-pink-600 hover:bg-pink-600 focus:ring-pink-200; - - &:disabled { - @apply bg-pink-300 border-pink-300; - @apply dark:bg-transparent dark:border-pink-400; - } - - .dark & { - @apply border-pink-600 bg-transparent text-pink-600 hover:border-pink-500 hover:text-pink-500 focus:ring-pink-500; - } - } - - &.gray { - @apply border-gray-500 bg-gray-500 text-white hover:border-gray-600 hover:bg-gray-600 focus:ring-gray-200; - - &:disabled { - @apply bg-gray-300 border-gray-300; - @apply dark:bg-transparent dark:border-gray-400; - } - - .dark & { - @apply border-gray-600 bg-transparent text-gray-600 hover:border-gray-500 hover:text-gray-500 focus:ring-gray-500; - } - } - - &.no-border{ - @apply border-0 hover:border-0 focus:border-0 ring-0 focus:ring-0 bg-transparent hover:bg-transparent focus:bg-transparent shadow-none hover:shadow-none focus:shadow-none; - } - } - - .button-group { - @apply inline-flex -space-x-0 divide-x overflow-hidden rounded-lg border border-transparent shadow-sm; - @apply divide-gray-300 border-gray-300 dark:divide-dark-500 dark:border-dark-500; - - & .btn { - @apply border-0 ring-0 focus:ring-0; - } - } - - .general-toast { - .notification-title { - font-size: 16px; - } - - .notification-content { - font-size: 14px; - } - - .vue-notification { - @apply duration-200 ease-in-out shadow-md hover:shadow-lg; - } - } - - .form-toast { - left: calc(50% - 150px); - @apply pt-2 mx-auto mb-3; - - .notification-title { - font-size: 14px; - } - - .notification-content { - font-size: 12px; - } - } -}
\ No newline at end of file diff --git a/extension/src/assets/toast.scss b/extension/src/assets/toast.scss new file mode 100644 index 0000000..3ddc3ac --- /dev/null +++ b/extension/src/assets/toast.scss @@ -0,0 +1,26 @@ +.general-toast { + .notification-title { + font-size: 16px; + } + + .notification-content { + font-size: 14px; + } + + .vue-notification { + @apply duration-200 ease-in-out shadow-md hover:shadow-lg; + } +} + +.form-toast { + left: calc(50% - 150px); + @apply pt-2 mx-auto mb-3; + + .notification-title { + font-size: 14px; + } + + .notification-content { + font-size: 12px; + } +} diff --git a/extension/src/entries/background/server-api/endpoints.ts b/extension/src/entries/background/server-api/endpoints.ts index a7f1488..b27bfa9 100644 --- a/extension/src/entries/background/server-api/endpoints.ts +++ b/extension/src/entries/background/server-api/endpoints.ts @@ -20,7 +20,7 @@ import { Method } from "axios"; export interface EndpointDefinition { readonly method: Method path(request?: any): string - onRequest: (request?: any) => Promise<any> + onRequest: (...request: any) => Promise<any> onResponse: (response: any, request?: any) => Promise<any> } @@ -42,7 +42,7 @@ export const initEndponts = () => { return endpoints.get(id); } - const execRequest = async <T>(id: string, request?: any): Promise<T> => { + const execRequest = async <T>(id: string, ...request: any): Promise<T> => { const endpoint = getEndpoint(id); if (!endpoint) { throw new Error(`Endpoint ${id} not found`); @@ -52,7 +52,7 @@ export const initEndponts = () => { const path = endpoint.path(request); //Execute the request handler - const req = await endpoint.onRequest(request); + const req = await endpoint.onRequest(...request); //Get axios const axios = useAxios(null); diff --git a/extension/src/entries/background/server-api/index.ts b/extension/src/entries/background/server-api/index.ts index 3e1ada0..ee6582d 100644 --- a/extension/src/entries/background/server-api/index.ts +++ b/extension/src/entries/background/server-api/index.ts @@ -15,9 +15,10 @@ import { Ref } from "vue" +import { get } from '@vueuse/core' import { WebMessage } from "@vnuge/vnlib.browser" import { initEndponts } from "./endpoints" -import { NostrEvent, NostrPubKey, NostrRelay } from "../types" +import { NostrEvent } from "../types" export enum Endpoints { GetKeys = 'getKeys', @@ -35,7 +36,7 @@ export const initApi = (nostrUrl: Ref<string>) => { registerEndpoint({ id: Endpoints.GetKeys, method: 'GET', - path: () => `${nostrUrl.value}?type=getKeys`, + path: () => `${get(nostrUrl)}?type=getKeys`, onRequest: () => Promise.resolve(), onResponse: (response) => Promise.resolve(response) }) @@ -43,7 +44,7 @@ export const initApi = (nostrUrl: Ref<string>) => { registerEndpoint({ id: Endpoints.DeleteKey, method: 'DELETE', - path: (key: NostrPubKey) => `${nostrUrl.value}?type=identity&key_id=${key.Id}`, + path: ([key]) => `${get(nostrUrl)}?type=identity&key_id=${key.Id}`, onRequest: () => Promise.resolve(), onResponse: (response: WebMessage) => response.getResultOrThrow() }) @@ -51,8 +52,8 @@ export const initApi = (nostrUrl: Ref<string>) => { registerEndpoint({ id: Endpoints.SignEvent, method: 'POST', - path: () => `${nostrUrl.value}?type=signEvent`, - onRequest: (event: NostrEvent) => Promise.resolve(event), + path: () => `${get(nostrUrl)}?type=signEvent`, + onRequest: ([event]) => Promise.resolve(event), onResponse: async (response: WebMessage<NostrEvent>) => { return response.getResultOrThrow() } @@ -61,7 +62,7 @@ export const initApi = (nostrUrl: Ref<string>) => { registerEndpoint({ id: Endpoints.GetRelays, method: 'GET', - path: () => `${nostrUrl.value}?type=getRelays`, + path: () => `${get(nostrUrl)}?type=getRelays`, onRequest: () => Promise.resolve(), onResponse: (response) => Promise.resolve(response) }) @@ -69,8 +70,8 @@ export const initApi = (nostrUrl: Ref<string>) => { registerEndpoint({ id: Endpoints.SetRelay, method: 'POST', - path: () => `${nostrUrl.value}?type=relay`, - onRequest: (relay: NostrRelay) => Promise.resolve(relay), + path: () => `${get(nostrUrl)}?type=relay`, + onRequest: ([relay]) => Promise.resolve(relay), onResponse: (response) => Promise.resolve(response) }) diff --git a/extension/src/entries/contentScript/primary/main.js b/extension/src/entries/contentScript/primary/main.js index 24ef4ef..047d0e9 100644 --- a/extension/src/entries/contentScript/primary/main.js +++ b/extension/src/entries/contentScript/primary/main.js @@ -21,7 +21,7 @@ import Notification from '@kyvg/vue3-notification' import '@fontsource/noto-sans-masaram-gondi' //We need inline styles to inject into the shadow dom -import tw from "~/assets/tailwind.scss?inline"; +import tw from "~/assets/all.scss?inline"; import localStyle from './style.scss?inline' renderContent([], (appRoot, shadowRoot) => { diff --git a/extension/src/entries/options/App.vue b/extension/src/entries/options/App.vue index f22feb0..f55b73b 100644 --- a/extension/src/entries/options/App.vue +++ b/extension/src/entries/options/App.vue @@ -3,25 +3,25 @@ <notifications class="toaster" group="form" position="top-right" /> - <div class="container flex w-full p-4 mx-auto mt-8 text-gray-800 dark:text-gray-200"> + <div class="container flex w-full p-4 mx-auto mt-8 text-black dark:text-white"> <div class="w-full max-w-4xl mx-auto"> <div class=""> - <h3>NVault</h3> + <h2>NVault</h2> </div> <TabGroup :selected-index="selectedTab" @change="id => selectedTab = id" > <TabList class="flex gap-3 pb-2 border-b border-gray-300 dark:border-dark-500"> <Tab v-slot="{ selected }"> - <button class="border-b-2" :class="[selected ? 'border-primary-500' : 'border-transparent']"> + <button class="tab-title" :class="{ selected }"> Identities </button> </Tab> <Tab v-slot="{ selected }"> - <button class="border-b-2" :class="[selected ? 'border-primary-500' : 'border-transparent']"> + <button class="tab-title" :class="{ selected }"> Privacy </button> </Tab> <Tab v-slot="{ selected }"> - <button class="border-b-2" :class="[selected ? 'border-primary-500' : 'border-transparent']"> + <button class="tab-title" :class="{ selected }"> Settings </button> </Tab> @@ -82,7 +82,7 @@ <div class="flex flex-col w-full max-w-md mx-auto mt-3"> <div class=""> <div class="text-sm">User Name</div> - <input class="w-full primary" type="text" v-model="keyBuffer.UserName"/> + <input class="w-full input" type="text" v-model="keyBuffer.UserName"/> </div> <div class="gap-2 my-3 ml-auto"> <button class="rounded btn sm primary" @click="onUpdate">Update</button> @@ -187,6 +187,14 @@ main { max-width: 230px; } +.tab-title{ + @apply border-b-2 border-transparent dark:text-gray-200; + + &.selected{ + @apply dark:border-gray-200 border-black; + } +} + .id-card{ @apply flex md:flex-row flex-col gap-2 p-3 text-sm duration-75 ease-in-out border-2 rounded-lg shadow-md cursor-pointer; @apply bg-white dark:bg-dark-700 border-gray-200 hover:border-gray-400 dark:border-dark-500 hover:dark:border-dark-200; diff --git a/extension/src/entries/options/components/Identities.vue b/extension/src/entries/options/components/Identities.vue index c86a6ac..d7fd75d 100644 --- a/extension/src/entries/options/components/Identities.vue +++ b/extension/src/entries/options/components/Identities.vue @@ -1,6 +1,6 @@ <template> <div class="sm:px-3"> - <div class="flex justify-end gap-2"> + <div class="flex justify-end gap-2 text-black dark:text-white"> <div class=""> <div class=""> <button class="rounded btn sm" @click="onNip05Download"> @@ -11,24 +11,26 @@ </div> <div class="mb-2"> <Popover class="relative" v-slot="{ open }"> - <PopoverButton class="rounded btn primary sm">Create</PopoverButton> - <PopoverOverlay v-if="open" class="fixed inset-0 bg-black opacity-30" /> - <PopoverPanel class="absolute z-10 mt-2 md:-left-12" v-slot="{ close }"> - <div class="p-4 bg-white border border-gray-200 rounded-md shadow-lg dark:border-dark-300 dark:bg-dark-700"> - <div class="text-sm w-72"> + <PopoverButton class="rounded btn sm">Create</PopoverButton> + <PopoverOverlay v-if="open" class="fixed inset-0 bg-black opacity-50" /> + <PopoverPanel class="absolute z-10 mt-2 md:-right-0" v-slot="{ close }"> + <div class="p-3 bg-white border border-gray-200 rounded shadow-lg dark:border-dark-600 dark:bg-dark-900"> + <div class="text-sm w-80"> <form @submit.prevent="e => onCreate(e, close)"> - Create new nostr identity - <div class="mt-2"> - <input class="w-full primary" type="text" name="username" placeholder="User Name"/> + <span class="text-lg dark:text-gray-200"> + Create keypair + </span> + <div class="mt-4"> + <input class="w-full rounded input" type="text" name="username" placeholder="username"/> </div> - <div class="mt-2"> - <input class="w-full primary" type="text" name="key" placeholder="Existing key?"/> - <div class="p-1.5 text-xs text-gray-600 dark:text-gray-300"> + <div class="mt-3"> + <input class="w-full rounded input" type="text" name="key" placeholder="Existing secret key?"/> + <div class="p-1.5 text-xs text-gray-600 dark:text-gray-400"> Optional, hexadecimal private key (64 characters) </div> </div> <div class="flex justify-end mt-2"> - <button class="rounded btn sm primary" type="submit">Create</button> + <button class="rounded sm btn" type="submit">Create</button> </div> </form> </div> @@ -38,47 +40,38 @@ </div> </div> <div v-for="key in allKeys" :key="key" class="mt-2 mb-3"> - <div class="id-card" :class="{'selected': isSelected(key)}" @click.self="selectKey(key)"> + <div class="" :class="{'selected': isSelected(key)}" @click.self="selectKey(key)"> - <div class="flex flex-col min-w-0" @click="selectKey(key)"> - <div class="py-2"> - - <table class="w-full text-sm text-left border-collapse"> - <thead class=""> - <tr> - <th scope="col" class="p-2 font-medium">Nip 05</th> - <th scope="col" class="p-2 font-medium">Modified</th> - <th scope="col" class="p-2 font-medium"></th> - </tr> - </thead> - <tbody class="border-t border-gray-100 divide-y divide-gray-100 dark:border-dark-500 dark:divide-dark-500"> - <tr> - <th class="p-2 font-medium">{{ key.UserName }}</th> - <td class="p-2">{{ prettyPrintDate(key) }}</td> - <td class="flex justify-end p-2 ml-auto text-sm font-medium"> - <div class="ml-auto button-group"> - <button class="btn sm borderless" @click="copy(key.PublicKey)"> - <fa-icon icon="copy"/> - </button> - <button class="btn sm borderless" @click="editKey(key)"> - <fa-icon icon="edit"/> - </button> - <button class="btn sm red borderless" @click="onDeleteKey(key)"> - <fa-icon icon="trash" /> - </button> - </div> - </td> - </tr> - </tbody> - </table> - - </div> - <div class="py-2 overflow-hidden border-gray-500 border-y dark:border-dark-500 text-ellipsis"> - <span class="font-semibold">pub:</span> - <span class="ml-1">{{ key.PublicKey }}</span> + <div class="mb-8"> + <div class="cursor-pointer w-fit" @click="selectKey(key)"> + <h3 :class="[ isSelected(key) ? 'underline' : 'dark:hover:text-gray-300 hover:text-gray-700']" class="duration-100 ease-out"> + {{ key.UserName }} + </h3> </div> - <div class="py-2"> - <strong>Id:</strong> {{ key.Id }} + <div class="mt-3"> + <p class="text-xs text-gray-700 truncate dark:text-gray-300"> + {{ key.PublicKey }} + </p> + <div class="flex flex-row gap-3 mt-1 text-xs text-gray-600 dark:text-gray-500"> + <div class=""> + {{ prettyPrintDate(key) }} + </div> + <div class=""> + <button class="text-red-700" @click="onDeleteKey(key)"> + Delete + </button> + </div> + <div class=""> + <button class="" @click="editKey(key)"> + Edit + </button> + </div> + <div class=""> + <button class="" @click="copy(key.PublicKey)"> + Copy + </button> + </div> + </div> </div> </div> </div> @@ -94,7 +87,8 @@ import { ref, toRefs } from "vue"; import { Popover, PopoverButton, - PopoverPanel + PopoverPanel, + PopoverOverlay } from '@headlessui/vue' import { apiCall, configureNotifier } from '@vnuge/vnlib.browser'; import { useManagment, useStatus } from '~/bg-api/options.ts'; diff --git a/extension/src/entries/options/components/SiteSettings.vue b/extension/src/entries/options/components/SiteSettings.vue index eafe8f3..01d3eac 100644 --- a/extension/src/entries/options/components/SiteSettings.vue +++ b/extension/src/entries/options/components/SiteSettings.vue @@ -8,32 +8,51 @@ </h3> <div class="my-6"> <fieldset :disabled="waiting"> - <div class="w-full"> - <div class="flex flex-row justify-between"> - <label class="mr-2">Always on NIP-07</label> + <div class=""> + <div class="w-full"> + <div class="flex flex-row w-full"> + <Switch + v-model="buffer.autoInject" + :class="buffer.autoInject ? 'bg-black dark:bg-gray-50' : 'bg-gray-200 dark:bg-dark-600'" + class="relative inline-flex items-center h-5 rounded-full w-11" + > + <span class="sr-only">NIP-07</span> + <span + :class="buffer.autoInject ? 'translate-x-6' : 'translate-x-1'" + class="inline-block w-4 h-4 transition transform bg-white rounded-full dark:bg-dark-900" + /> + </Switch> + <div class="my-auto ml-2 text-sm dark:text-gray-200"> + Always on NIP-07 + </div> + </div> + </div> + </div> + + <div class="mt-3"> + <div class="flex flex-row w-fit"> <Switch - v-model="buffer.autoInject" - :class="buffer.autoInject ? 'bg-primary-500 dark:bg-primary-600' : 'bg-gray-200 dark:bg-dark-600'" - class="relative inline-flex items-center h-6 ml-auto rounded-full w-11" + v-model="v$.heartbeat.$model" + :class="v$.heartbeat.$model ? 'bg-black dark:bg-white' : 'bg-gray-200 dark:bg-dark-600'" + class="relative inline-flex items-center h-5 mx-auto rounded-full w-11" > - <span class="sr-only">NIP-07</span> + <span class="sr-only">Stay logged in</span> <span - :class="buffer.autoInject ? 'translate-x-6' : 'translate-x-1'" - class="inline-block w-4 h-4 transition transform bg-white rounded-full" + :class="v$.heartbeat.$model ? 'translate-x-6' : 'translate-x-1'" + class="inline-block w-4 h-4 transition transform rounded-full bg-gray-50 dark:bg-dark-900" /> </Switch> + <div class="my-auto ml-2 text-sm dark:text-gray-200"> + Stay logged-in + </div> </div> </div> - <p class="mt-1 text-xs"> - Enable auto injection of <code>window.nostr</code> support to all websites. Sites may be able to - track you if you enable this feature. - </p> </fieldset> </div> <h3 class="text-center"> Server settings </h3> - <p class="text-sm"> + <p class="text-xs dark:text-gray-400"> You must be careful when editing these settings as you may loose connection to your vault server if you input the wrong values. </p> @@ -52,43 +71,25 @@ </div> <fieldset :disabled="waiting || !editMode"> <div class="pl-1 mt-2"> - <div class="flex flex-row w-full"> - <div> - <label class="mb-2">Stay logged in</label> - <Switch - v-model="v$.heartbeat.$model" - :class="v$.heartbeat.$model ? 'bg-primary-500 dark:bg-primary-600' : 'bg-gray-200 dark:bg-dark-600'" - class="relative inline-flex items-center h-6 mx-auto rounded-full w-11" - > - <span class="sr-only">Stay logged in</span> - <span - :class="v$.heartbeat.$model ? 'translate-x-6' : 'translate-x-1'" - class="inline-block w-4 h-4 transition transform bg-white rounded-full" - /> - </Switch> - </div> - <div class="my-auto text-xs"> - Enables keepalive messages to regenerate credentials when they expire - </div> - </div> + </div> <div class="mt-2"> <label class="pl-1">BaseUrl</label> - <input class="w-full primary" v-model="v$.apiUrl.$model" :class="{'error': v$.apiUrl.$invalid }" /> + <input class="w-full input" v-model="v$.apiUrl.$model" :class="{'error': v$.apiUrl.$invalid }" /> <p class="pl-1 mt-1 text-xs text-red-500"> * The http path to the vault server (must start with http:// or https://) </p> </div> <div class="mt-2"> <label class="pl-1">Account endpoint</label> - <input class="w-full primary" v-model="v$.accountBasePath.$model" :class="{ 'error': v$.accountBasePath.$invalid }" /> + <input class="w-full input" v-model="v$.accountBasePath.$model" :class="{ 'error': v$.accountBasePath.$invalid }" /> <p class="pl-1 mt-1 text-xs text-red-500"> * This is the path to the account server endpoint (must start with /) </p> </div> <div class="mt-2"> <label class="pl-1">Nostr endpoint</label> - <input class="w-full primary" v-model="v$.nostrEndpoint.$model" :class="{ 'error': v$.nostrEndpoint.$invalid }" /> + <input class="w-full input" v-model="v$.nostrEndpoint.$model" :class="{ 'error': v$.nostrEndpoint.$invalid }" /> <p class="pl-1 mt-1 text-xs text-red-500"> * This is the path to the Nostr plugin endpoint path (must start with /) </p> @@ -155,6 +156,7 @@ const editMode = ref(false); const toggleEdit = useToggle(editMode); const autoInject = computed(() => buffer.autoInject) +const heartbeat = computed(() => buffer.heartbeat) const onSave = async () => { @@ -217,16 +219,20 @@ const testConnection = async () =>{ const loadConfig = async () => { const config = await getSiteConfig(); apply(config); +} + +const init = async () => { + await loadConfig(); //Watch for changes to autoinject value and publish changes when it does - watchDebounced(autoInject, publishConfig, { debounce: 500 }) + watchDebounced(autoInject, publishConfig, { debounce: 500, immediate: false }) + watchDebounced(heartbeat, publishConfig, { debounce: 500, immediate: false }) } //If edit mode is toggled off, reload config watch(editMode, v => v ? null : loadConfig()); - -loadConfig(); +init(); </script> diff --git a/extension/src/entries/options/index.html b/extension/src/entries/options/index.html index 72f2de7..976e7ea 100644 --- a/extension/src/entries/options/index.html +++ b/extension/src/entries/options/index.html @@ -10,7 +10,7 @@ @apply bg-dark-900; } body{ - @apply bg-gray-50; + @apply bg-white; } </style> </head> diff --git a/extension/src/entries/options/main.js b/extension/src/entries/options/main.js index 92a4868..b9892ba 100644 --- a/extension/src/entries/options/main.js +++ b/extension/src/entries/options/main.js @@ -17,15 +17,15 @@ import { createApp } from "vue"; import App from "./App.vue"; import '@fontsource/noto-sans-masaram-gondi' -import "~/assets/tailwind.scss"; +import "~/assets/all.scss"; import Notifications from "@kyvg/vue3-notification"; /* FONT AWESOME CONFIG */ import { library } from '@fortawesome/fontawesome-svg-core' -import { faChevronLeft, faCopy, faDownload, faEdit, faExternalLinkAlt, faLock, faLockOpen, faMoon, faSun, faTrash } from '@fortawesome/free-solid-svg-icons' +import { faChevronLeft, faChevronRight, faCopy, faDownload, faEdit, faExternalLinkAlt, faLock, faLockOpen, faMoon, faSun, faTrash } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' -library.add(faCopy, faEdit, faChevronLeft, faMoon, faSun, faLock, faLockOpen, faExternalLinkAlt, faTrash, faDownload) +library.add(faCopy, faEdit, faChevronLeft, faMoon, faSun, faLock, faLockOpen, faExternalLinkAlt, faTrash, faDownload, faChevronRight) createApp(App) .use(Notifications) diff --git a/extension/src/entries/popup/Components/IdentitySelection.vue b/extension/src/entries/popup/Components/IdentitySelection.vue index d95dedb..d1a7333 100644 --- a/extension/src/entries/popup/Components/IdentitySelection.vue +++ b/extension/src/entries/popup/Components/IdentitySelection.vue @@ -2,7 +2,7 @@ <div class="px-3 text-left"> <div class="w-full"> <div class=""> - <select class="w-full primary" + <select class="w-full input" :disabled="waiting" :value="selected?.Id" @change.prevent="onSelected" diff --git a/extension/src/entries/popup/Components/Login.vue b/extension/src/entries/popup/Components/Login.vue index 495b64e..c863430 100644 --- a/extension/src/entries/popup/Components/Login.vue +++ b/extension/src/entries/popup/Components/Login.vue @@ -3,7 +3,7 @@ <form class="" @submit.prevent="onSubmit"> <fieldset class="px-4 input-container"> <label class="">Please enter your authentication token</label> - <textarea class="w-full primary" v-model="token" rows="5"> + <textarea class="w-full input" v-model="token" rows="5"> </textarea> </fieldset> <div class="flex justify-end mt-2"> diff --git a/extension/src/entries/popup/Components/PageContent.vue b/extension/src/entries/popup/Components/PageContent.vue index c9b2d5f..eda9bab 100644 --- a/extension/src/entries/popup/Components/PageContent.vue +++ b/extension/src/entries/popup/Components/PageContent.vue @@ -5,8 +5,8 @@ > <div class="flex flex-row w-full px-1 pl-4"> - <div class="flex-auto my-auto font-mono text-sm"> - A nostr credential vault + <div class="flex-auto my-auto"> + <h3>NVault</h3> </div> <div class="my-auto" v-if="loggedIn"> <button class="rounded btn sm red" @click.prevent="logout"> diff --git a/extension/src/entries/popup/main.js b/extension/src/entries/popup/main.js index d9101ab..4a32bb7 100644 --- a/extension/src/entries/popup/main.js +++ b/extension/src/entries/popup/main.js @@ -17,7 +17,7 @@ import { createApp } from "vue"; import App from "./App.vue"; import Notifications from "@kyvg/vue3-notification"; import '@fontsource/noto-sans-masaram-gondi' -import "~/assets/tailwind.scss"; +import "~/assets/all.scss"; /* FONT AWESOME CONFIG */ import { library } from '@fortawesome/fontawesome-svg-core' |