aboutsummaryrefslogtreecommitdiff
path: root/extension
diff options
context:
space:
mode:
Diffstat (limited to 'extension')
-rw-r--r--extension/src/assets/all.scss14
-rw-r--r--extension/src/assets/buttons.scss44
-rw-r--r--extension/src/assets/etc.scss25
-rw-r--r--extension/src/assets/footer.scss3
-rw-r--r--extension/src/assets/header.scss3
-rw-r--r--extension/src/assets/headings.scss32
-rw-r--r--extension/src/assets/inputs.scss71
-rw-r--r--extension/src/assets/modals.scss29
-rw-r--r--extension/src/assets/tailwind.scss354
-rw-r--r--extension/src/assets/toast.scss26
-rw-r--r--extension/src/entries/background/server-api/endpoints.ts6
-rw-r--r--extension/src/entries/background/server-api/index.ts17
-rw-r--r--extension/src/entries/contentScript/primary/main.js2
-rw-r--r--extension/src/entries/options/App.vue20
-rw-r--r--extension/src/entries/options/components/Identities.vue100
-rw-r--r--extension/src/entries/options/components/SiteSettings.vue84
-rw-r--r--extension/src/entries/options/index.html2
-rw-r--r--extension/src/entries/options/main.js6
-rw-r--r--extension/src/entries/popup/Components/IdentitySelection.vue2
-rw-r--r--extension/src/entries/popup/Components/Login.vue2
-rw-r--r--extension/src/entries/popup/Components/PageContent.vue4
-rw-r--r--extension/src/entries/popup/main.js2
-rw-r--r--extension/tailwind.config.js89
23 files changed, 463 insertions, 474 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'
diff --git a/extension/tailwind.config.js b/extension/tailwind.config.js
index be556e2..a8cdaa6 100644
--- a/extension/tailwind.config.js
+++ b/extension/tailwind.config.js
@@ -1,4 +1,5 @@
import colors from 'tailwindcss/colors'
+import plugin from 'tailwindcss/plugin'
export default {
cpurge: ['./*.html', './src/**/*.{vue,js,ts,jsx,tsx,css}'],
@@ -51,5 +52,91 @@ export default {
}
},
},
- plugins: []
+ plugins: [
+ //Adds button variants for each color
+ plugin(({ theme, addUtilities }) => {
+ const coloredButtons = {}
+
+ for (let color in theme('colors')) {
+
+ //Buttons must also have the .btn class
+ coloredButtons[`.btn.${color}`] = {
+ 'color': theme(`colors.white`),
+ 'border-color': theme(`colors.${color}.500`),
+ 'background-color': theme(`colors.${color}.500`),
+
+ '&:hover': {
+ 'border-color': theme(`colors.${color}.600`),
+ 'background-color': theme(`colors.${color}.600`),
+ },
+
+ '&:active': {
+ 'border-color': theme(`colors.${color}.700`),
+ 'background-color': theme(`colors.${color}.700`),
+ },
+
+ '&:focus': {
+ '--tw-ring-color': theme(`colors.${color}.500`),
+ },
+
+ '&:disabled': {
+ 'border-color': theme(`colors.${color}.300`),
+ 'background-color': theme(`colors.${color}.300`),
+ color: theme(`colors.white`),
+ },
+
+ '&.borderless, &.no-border, &.b-0': {
+ 'color': theme(`colors.${color}.500`),
+ '&:hover': {
+ 'color': theme(`colors.${color}.600`),
+ },
+ 'border': 'none',
+ 'background-color': 'transparent',
+ },
+
+ '.dark &': {
+ 'border-color': theme(`colors.${color}.600`),
+ 'background-color': 'transparent',
+ 'color': theme(`colors.${color}.600`),
+
+ '&:hover': {
+ 'border-color': theme(`colors.${color}.500`),
+ 'color': theme(`colors.${color}.500`),
+ },
+
+ '&:focus': {
+ '--tw-ring-color': theme(`colors.${color}.500`),
+ },
+
+ '&:disabled': {
+ 'border-color': theme(`colors.${color}.800`),
+ 'color': theme(`colors.${color}.800`),
+ }
+ }
+ }
+ }
+
+ addUtilities(coloredButtons)
+ }),
+
+ //Plugin for input variants
+ plugin(({ theme, addUtilities }) => {
+ const coloredInputs = {}
+
+ for (let color in theme('colors')) {
+ coloredInputs[`.input.${color}`] = {
+ 'outline': 'none',
+
+ '&:focus, &:active, &::after, &:focus:hover': {
+ 'border-color': theme(`colors.${color}.500`),
+ 'dark &': {
+ 'border-color': theme(`colors.${color}.600`),
+ }
+ }
+ }
+ }
+
+ addUtilities(coloredInputs)
+ })
+ ]
}