Rumah > pembangunan bahagian belakang > Golang > Apl desktop pengurus kata laluan minimalis: pencerobohan ke dalam rangka kerja Golang's Wails (Bahagian 2)

Apl desktop pengurus kata laluan minimalis: pencerobohan ke dalam rangka kerja Golang's Wails (Bahagian 2)

Susan Sarandon
Lepaskan: 2024-12-30 09:50:16
asal
495 orang telah melayarinya

Hai sekali lagi, pengekod! Pada bahagian pertama siri pendek ini kami melihat penciptaan dan pengendalian aplikasi desktop untuk menyimpan dan menyulitkan kata laluan kami yang dibuat dengan rangka kerja Wails. Kami juga membuat penerangan tentang bahagian belakang Go dan cara kami mengikatnya ke bahagian hujung hadapan.

Dalam bahagian ini, kita akan berurusan dengan antara muka pengguna. Seperti yang kami nyatakan dalam siaran itu, Wails membenarkan kami menggunakan mana-mana rangka kerja web yang kami suka, malah Vanilla JS, untuk membina GUI kami. Seperti yang saya katakan, nampaknya pencipta Wails mempunyai keutamaan untuk Svelte, kerana mereka selalu menyebutnya sebagai pilihan pertama mereka. The Wails CLI (dalam versi semasanya) apabila kami meminta untuk mencipta projek dengan Svelte Typescript (waiils init -n myproject -t svelte-ts) menjana perancah dengan Svelte3. Seperti yang telah saya beritahu anda, jika anda lebih suka menggunakan Svelte5 (dan ciri baharunya) saya mempunyai skrip bash yang mengautomasikan penciptaannya (dalam apa jua keadaan, anda perlu memasang CLI Wails). Di samping itu, ia menambah Taildwindcss Daisyui yang nampaknya pada saya gabungan sempurna untuk reka bentuk antara muka.

Sebenarnya saya telah bekerja dahulu dengan Vanilla Js dan Vue, kemudian dengan React, malah dengan perpustakaan aneh yang bagi kebanyakan orang adalah HTMX (yang perlu saya katakan bahawa saya suka ❤️). Tetapi Svelte membuatkan anda jatuh cinta dari awal, dan saya harus mengatakan bahawa semasa bereksperimen dengan Wails, saya menggunakannya buat kali pertama (dan saya berjanji untuk terus menggunakannya…). Tetapi seselesa pun rangka kerja web, kita mesti mengingatkan pembangun bahagian belakang bahawa bahagian hadapan tidak semudah itu ?!!

Tetapi mari kita ke intinya.

I - Lihat pada struktur bahagian hadapan

Jika anda telah menggunakan mana-mana rangka kerja web, anda akan mengenali dengan cepat bahawa Wails CLI menggunakan ViteJs di bawah hud:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│   ├── App.svelte
│   ├── assets
│   │   ├── fonts
│   │   │   ├── nunito-v16-latin-regular.woff2
│   │   │   └── OFL.txt
│   │   └── images
│   │       └── logo-universal.png
│   ├── lib
│   │   ├── BackBtn.svelte
│   │   ├── BottomActions.svelte
│   │   ├── EditActions.svelte
│   │   ├── EntriesList.svelte
│   │   ├── Language.svelte
│   │   ├── popups
│   │   │   ├── alert-icons.ts
│   │   │   └── popups.ts
│   │   ├── ShowPasswordBtn.svelte
│   │   └── TopActions.svelte
│   ├── locales
│   │   ├── en.json
│   │   └── es.json
│   ├── main.ts
│   ├── pages
│   │   ├── About.svelte
│   │   ├── AddPassword.svelte
│   │   ├── Details.svelte
│   │   ├── EditPassword.svelte
│   │   ├── Home.svelte
│   │   ├── Login.svelte
│   │   └── Settings.svelte
│   ├── style.css
│   └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │   ├── main
    │   │   ├── App.d.ts
    │   │   └── App.js
    │   └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Jika anda telah menggunakan mana-mana rangka kerja web yang dihasilkan oleh Vite anda tidak akan terkejut dengan fail konfigurasinya. Di sini saya menggunakan Svelte5 (ditambah konfigurasi Taildwindcss Daisyui) yang menjana skrip bash saya sendiri, seperti yang telah saya beritahu anda. Kami juga menggunakan TypeScript, yang akan memudahkan pembangunan bahagian hadapan, jadi anda juga boleh melihat konfigurasinya.

Tetapi perkara penting dalam penjelasan ini ialah kandungan folder wailsjs. Di sinilah kompilasi yang dilakukan oleh Wails telah melakukan keajaibannya. Subfolder go ialah tempat kaedah "diterjemahkan" kepada Js/Ts bahagian hujung belakang yang perlu berinteraksi dengan hujung hadapan disimpan. Contohnya, dalam main/App.js (atau versi TypeScriptnya, main/App.d.ts) terdapat semua kaedah (awam) struktur Apl yang dieksport:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│   ├── App.svelte
│   ├── assets
│   │   ├── fonts
│   │   │   ├── nunito-v16-latin-regular.woff2
│   │   │   └── OFL.txt
│   │   └── images
│   │       └── logo-universal.png
│   ├── lib
│   │   ├── BackBtn.svelte
│   │   ├── BottomActions.svelte
│   │   ├── EditActions.svelte
│   │   ├── EntriesList.svelte
│   │   ├── Language.svelte
│   │   ├── popups
│   │   │   ├── alert-icons.ts
│   │   │   └── popups.ts
│   │   ├── ShowPasswordBtn.svelte
│   │   └── TopActions.svelte
│   ├── locales
│   │   ├── en.json
│   │   └── es.json
│   ├── main.ts
│   ├── pages
│   │   ├── About.svelte
│   │   ├── AddPassword.svelte
│   │   ├── Details.svelte
│   │   ├── EditPassword.svelte
│   │   ├── Home.svelte
│   │   ├── Login.svelte
│   │   └── Settings.svelte
│   ├── style.css
│   └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │   ├── main
    │   │   ├── App.d.ts
    │   │   └── App.js
    │   └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Semuanya membalas janji. Jika janji "membungkus" beberapa struktur Go yang digunakan sebagai jenis pulangan atau fungsi masing-masing mengambil jenis hujah, akan ada modul (models.ts, ditaip dalam kes ini, kerana kami menggunakan TypeScript) yang mengandungi kelas yang sepadan dengan Go struktur dan pembinanya dalam ruang nama.

Selain itu, subfolder masa jalan mengandungi semua kaedah daripada pakej masa jalan Go yang membolehkan kami memanipulasi tetingkap dan peristiwa yang didengar atau dipancarkan dari atau ke bahagian belakang, masing-masing.

Folder src mengandungi fail yang akan disusun oleh Vite untuk menyimpannya dalam "frontend/dist" (dan dibenamkan dalam boleh laku akhir), seperti dalam mana-mana aplikasi web. Ambil perhatian bahawa, memandangkan kami menggunakan Tailwindcss, style.css mengandungi konfigurasi Tailwind asas serta mana-mana kelas CSS yang perlu kami gunakan. Selain itu, sebagai kelebihan menggunakan teknologi web untuk antara muka, kami boleh menggunakan satu atau lebih fon (aset/fon folder) dengan mudah atau menukarnya.

Untuk menyelesaikan gambaran keseluruhan ini, ambil perhatian bahawa apabila kami menyusun dalam mod pembangunan (raungan dev), selain membenarkan kami memuat semula panas, kami bukan sahaja dapat melihat perubahan yang dibuat (kedua-dua di bahagian belakang dan di bahagian hadapan) dalam tetingkap aplikasi itu sendiri, tetapi juga dalam pelayar web melalui alamat http://localhost:34115, sejak pelayan web dimulakan. Ini membolehkan anda menggunakan sambungan pembangunan penyemak imbas kegemaran anda. Walaupun mesti dikatakan bahawa Wails sendiri memberikan kami beberapa alat dev yang sangat berguna, apabila kami klik kanan pada tetingkap aplikasi (hanya dalam mod pembangunan) dan pilih "Inspect Element":

A minimalist password manager desktop app: a foray into Golang

II - Dan sekarang... menyelami HTML, CSS dan JavaScript ?


// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Seperti yang anda lihat, terdapat 4 pakej JavaScript yang telah saya tambahkan pada Svelte (selain daripada Tailwindcss Daisyui yang telah disebutkan):

  • svelte-copy, untuk memudahkan anda menyalin nama pengguna dan kata laluan ke papan keratan.
  • svelte-i18n, untuk pengendalian i18n, iaitu membenarkan pengguna menukar bahasa aplikasi.
  • svelte-spa-router, perpustakaan penghalaan kecil untuk Svelte, yang menjadikannya lebih mudah untuk menukar paparan dalam tetingkap aplikasi, kerana tidak berbaloi, dalam kes ini, untuk menggunakan penghalaan "rasmi" yang disediakan oleh SvelteKit.
  • sweetalert2, pada asasnya gunakannya untuk mencipta mod/kotak dialog dengan mudah dan cepat.

Titik masuk setiap SPA ialah fail main.js (atau main.ts), jadi mari kita mulakan dengan itu:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│   ├── App.svelte
│   ├── assets
│   │   ├── fonts
│   │   │   ├── nunito-v16-latin-regular.woff2
│   │   │   └── OFL.txt
│   │   └── images
│   │       └── logo-universal.png
│   ├── lib
│   │   ├── BackBtn.svelte
│   │   ├── BottomActions.svelte
│   │   ├── EditActions.svelte
│   │   ├── EntriesList.svelte
│   │   ├── Language.svelte
│   │   ├── popups
│   │   │   ├── alert-icons.ts
│   │   │   └── popups.ts
│   │   ├── ShowPasswordBtn.svelte
│   │   └── TopActions.svelte
│   ├── locales
│   │   ├── en.json
│   │   └── es.json
│   ├── main.ts
│   ├── pages
│   │   ├── About.svelte
│   │   ├── AddPassword.svelte
│   │   ├── Details.svelte
│   │   ├── EditPassword.svelte
│   │   ├── Home.svelte
│   │   ├── Login.svelte
│   │   └── Settings.svelte
│   ├── style.css
│   └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │   ├── main
    │   │   ├── App.d.ts
    │   │   └── App.js
    │   └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Saya telah menyerlahkan perkara yang telah saya tambahkan pada rangka yang dijana oleh Wails CLI. Pustaka svelte-i18n memerlukan fail JSON yang mengandungi terjemahan didaftarkan dalam fail main.js/ts, pada masa yang sama dengan menetapkan bahasa fallback/initial (walaupun seperti yang kita' Nanti, itu akan dimanipulasi kemudian berdasarkan apa yang pengguna telah pilih sebagai pilihan mereka). Fail JSON yang mengandungi terjemahan adalah dalam format:

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Saya mendapati sistem perpustakaan ini mudah dan mudah untuk memudahkan terjemahan aplikasi Svelte (anda boleh merujuk dokumentasinya untuk butiran lanjut):

/* package.json */
...
},
  "dependencies": {
    "svelte-copy": "^2.0.0",
    "svelte-i18n": "^4.0.1",
    "svelte-spa-router": "^4.0.1",
    "sweetalert2": "^11.14.5"
  }
...

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Anda juga boleh menggunakan tapak seperti ini, yang akan membantu anda menterjemah fail JSON ke dalam bahasa yang berbeza. Walau bagaimanapun, masalahnya ialah apabila anda mengisi fail .svelte anda dengan $format, anda perlu menjejakinya secara manual, yang membosankan dan mudah ralat. Saya tidak tahu apa-apa cara untuk mengautomasikan tugasan ini, jika sesiapa tahu, saya akan berminat jika anda memberitahu saya ?… Jika tidak, saya perlu memikirkan beberapa jenis skrip untuk melakukan kerja itu.

Langkah seterusnya dalam membina antara muka, seperti dalam mana-mana aplikasi Svelte, ialah fail App.svelte:

/* main.ts */

import { mount } from 'svelte'
import './style.css'
import App from './App.svelte'
import { addMessages, init } from "svelte-i18n"; // ⇐ ⇐
import en from './locales/en.json'; // ⇐ ⇐
import es from './locales/es.json'; // ⇐ ⇐

addMessages('en', en); // ⇐ ⇐
addMessages('es', es); // ⇐ ⇐

init({
  fallbackLocale: 'en', // ⇐ ⇐
  initialLocale: 'en', // ⇐ ⇐
});

const app = mount(App, {
  target: document.getElementById('app')!,
})

export default app

Salin selepas log masuk
Salin selepas log masuk

Di sini kami menggunakan GetMasterPassword yang merupakan mengikat yang dijana secara automatik apabila menyusun aplikasi dan yang telah diisytiharkan sebagai kaedah awam App struct (lihat bahagian pertama siri ini). Fungsi ini menanyakan pangkalan data dan, sekiranya terdapat kata laluan induk yang didaftarkan di dalamnya, ia menganggap pengguna telah didaftarkan (ia mengembalikan janji yang membungkus nilai boolean), memintanya memasukkan kata laluan tersebut untuk membolehkannya mengakses yang lain daripada pandangan. Jika tiada kata laluan induk dalam pangkalan data, pengguna dianggap sebagai "baru" dan apa yang diminta ialah dia menjana kata laluan sendiri untuk memasuki aplikasi buat kali pertama.

Akhir sekali, apabila memasang komponen Login.svelte kami melakukan sesuatu yang penting untuk seluruh aplikasi. Walaupun perpustakaan svelte-i18n memaksa kami untuk mengisytiharkan kod bahasa awal, seperti yang telah kami lihat, apabila memasang Login.svelte kami meminta pangkalan data (menggunakan pengikatan GetLanguage) untuk menyemak sama ada terdapat kod bahasa yang disimpan. Sekiranya pangkalan data mengembalikan rentetan kosong, iaitu, jika tiada bahasa yang dikonfigurasikan sebagai pilihan pengguna, svelte-i18n akan menggunakan nilai yang dikonfigurasikan sebagai initialLocale. Jika sebaliknya terdapat bahasa yang dikonfigurasikan, bahasa itu akan ditetapkan (locale.set(result);) dan acara "change_titles" akan dipancarkan, yang mana tajuk terjemahan bar tajuk dan dialog asli apl akan dihantar untuk bahagian belakang untuk dikendalikan:

/* frontend/src/locales/en.json */

{
    "language": "Language",
    "app_title": "Nu-i uita • minimalist password store",
    "select_directory": "Select the directory where to save the data export",
    "select_file": "Select the backup file to import",
    "master_password": "Master Password ?",
    "generate": "Generate",
    "insert": "Insert",
    "login": "Login",
    ...
}


/* frontend/src/locales/es.json */

{
    "language": "Idioma",
    "app_title": "Nu-i uita • almacén de contraseñas minimalista",
    "select_directory": "Selecciona el directorio donde guardar los datos exportados",
    "select_file": "Selecciona el archivo de respaldo que deseas importar",
    "master_password": "Contraseña Maestra ?",
    "generate": "Generar",
    "insert": "Insertar",
    "login": "Inciar sesión",
    ...
}

Salin selepas log masuk
Salin selepas log masuk

Berikut ialah logik untuk mengendalikan log masuk:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│   ├── App.svelte
│   ├── assets
│   │   ├── fonts
│   │   │   ├── nunito-v16-latin-regular.woff2
│   │   │   └── OFL.txt
│   │   └── images
│   │       └── logo-universal.png
│   ├── lib
│   │   ├── BackBtn.svelte
│   │   ├── BottomActions.svelte
│   │   ├── EditActions.svelte
│   │   ├── EntriesList.svelte
│   │   ├── Language.svelte
│   │   ├── popups
│   │   │   ├── alert-icons.ts
│   │   │   └── popups.ts
│   │   ├── ShowPasswordBtn.svelte
│   │   └── TopActions.svelte
│   ├── locales
│   │   ├── en.json
│   │   └── es.json
│   ├── main.ts
│   ├── pages
│   │   ├── About.svelte
│   │   ├── AddPassword.svelte
│   │   ├── Details.svelte
│   │   ├── EditPassword.svelte
│   │   ├── Home.svelte
│   │   ├── Login.svelte
│   │   └── Settings.svelte
│   ├── style.css
│   └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │   ├── main
    │   │   ├── App.d.ts
    │   │   └── App.js
    │   └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Ringkasnya: newPassword, keadaan terikat pada input yang mendapat apa yang jenis pengguna, mula-mula disemak oleh onLogin untuk melihat sama ada ia mempunyai sekurang-kurangnya 6 aksara dan kesemuanya ialah ASCII aksara, iaitu panjangnya hanya 1 bait (lihat sebabnya di bahagian I siri ini) oleh fungsi kecil ini const isAscii = (str: string): boolean => /^[x00-x7F] $/.test(str);. Jika semakan gagal fungsi kembali dan memaparkan amaran toast kepada pengguna. Selepas itu, jika tiada kata laluan induk disimpan dalam pangkalan data (isLogin = palsu), apa sahaja jenis pengguna disimpan oleh fungsi SaveMasterPassword (pengikatan yang dihasilkan oleh Wails); Jika janji itu berjaya diselesaikan (mengembalikan rentetan uuid sebagai Id rekod yang disimpan dalam pangkalan data), pengguna dibawa ke paparan rumah oleh penghala svelte-spa kaedah tolak perpustakaan. Sebaliknya, jika kata laluan melepasi semakan panjang dan ketiadaan bukan ASCII aksara dan terdapat kata laluan induk dalam DB (isLogin = benar) maka fungsi CheckMasterPassword mengesahkan identitinya terhadap yang disimpan dan sama ada membawa pengguna ke paparan utama (janji diselesaikan dengan benar) atau toast ditunjukkan menunjukkan bahawa kata laluan yang dimasukkan adalah tidak betul.

Pandangan tengah aplikasi dan pada masa yang sama yang paling kompleks ialah paparan rumah. HTMLnya sebenarnya dibahagikan kepada 3 komponen: bar butang atas dengan input carian (komponen TopActions), bar butang bawah (komponen BottomActions) dan kawasan tengah di mana jumlah entri kata laluan yang disimpan atau senarai ini dipaparkan menggunakan tetingkap boleh tatal (komponen EntriesList):

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Iaitu, ia menjadikan keadaan carian (Terma carian) sebagai rentetan kosong, supaya jika terdapat sebarang istilah carian ia ditetapkan semula dan dengan itu keseluruhan senarai ditunjukkan. Dan sebaliknya, ia menogol keadaan showList (props isEntriesList in TopActions) supaya komponen induk menunjukkan atau menyembunyikan senarai.

Seperti yang dapat kita lihat dalam rajah di atas, kedua-dua komponen anak berkongsi props yang sama dengan keadaan Terma carian ibu bapa. Komponen TopActions menangkap input daripada pengguna dan menghantarnya sebagai keadaan kepada komponen induk Laman Utama, yang seterusnya menghantarnya sebagai props kepada EntriesList komponen anaknya.

Logik utama untuk memaparkan senarai penuh atau senarai yang ditapis oleh istilah carian yang dimasukkan oleh pengguna dijalankan, seperti yang dijangkakan, oleh komponen EntriesList:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│   ├── App.svelte
│   ├── assets
│   │   ├── fonts
│   │   │   ├── nunito-v16-latin-regular.woff2
│   │   │   └── OFL.txt
│   │   └── images
│   │       └── logo-universal.png
│   ├── lib
│   │   ├── BackBtn.svelte
│   │   ├── BottomActions.svelte
│   │   ├── EditActions.svelte
│   │   ├── EntriesList.svelte
│   │   ├── Language.svelte
│   │   ├── popups
│   │   │   ├── alert-icons.ts
│   │   │   └── popups.ts
│   │   ├── ShowPasswordBtn.svelte
│   │   └── TopActions.svelte
│   ├── locales
│   │   ├── en.json
│   │   └── es.json
│   ├── main.ts
│   ├── pages
│   │   ├── About.svelte
│   │   ├── AddPassword.svelte
│   │   ├── Details.svelte
│   │   ├── EditPassword.svelte
│   │   ├── Home.svelte
│   │   ├── Login.svelte
│   │   └── Settings.svelte
│   ├── style.css
│   └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │   ├── main
    │   │   ├── App.d.ts
    │   │   └── App.js
    │   └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Seperti yang kami katakan, 2 prop diterima (listCounter dan carian) dan keadaan dikekalkan (biarkan entri: models.PasswordEntry[] = $state([]);). Apabila komponen dipasang atas permintaan pengguna, bahagian belakang diminta untuk senarai lengkap entri kata laluan yang disimpan. Jika tiada istilah carian, ia disimpan di negeri ini; jika ada, penapisan mudah tatasusunan yang diperolehi dilakukan dan ia disimpan dalam keadaan:

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Dalam senarai yang dipaparkan, pengguna boleh melakukan 2 tindakan. Yang pertama ialah untuk memaparkan butiran entri, yang dijalankan apabila dia mengklik pada butang yang sepadan: onclick={() => push(`/details/${entry.Id}`)}. Pada asasnya, kami memanggil kaedah tolak pustaka penghalaan untuk membawa pengguna ke paparan butiran, tetapi menghantar parameter Id yang sepadan dengan item yang dipersoalkan.

Tindakan lain yang boleh dilakukan oleh pengguna ialah memadamkan item daripada senarai. Jika dia mengklik pada butang yang sepadan, dia akan ditunjukkan pop timbul pengesahan, memanggil fungsi showAlert. Fungsi ini seterusnya memanggil showWarning, yang sebenarnya merupakan lapisan abstraksi di atas perpustakaan sweetalert2 (semua fungsi yang memanggil perpustakaan sweetalert2 berada di frontend/src/lib/popups/popups.ts). Jika pengguna mengesahkan tindakan pemadaman, pengikatan DeleteEntry dipanggil (untuk memadamkannya daripada DB) dan, sebaliknya, jika janji yang dipulangkan telah diselesaikan, deleteItem dipanggil (untuk memadamkannya daripada tatasusunan yang disimpan dalam keadaan entri) :

/* package.json */
...
},
  "dependencies": {
    "svelte-copy": "^2.0.0",
    "svelte-i18n": "^4.0.1",
    "svelte-spa-router": "^4.0.1",
    "sweetalert2": "^11.14.5"
  }
...

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Komponen lain bagi paparan Laman Utama (BottomActions) adalah lebih mudah: ia tidak menerima props dan terhad kepada mengubah hala pengguna ke pelbagai paparan (Tetapan, Perihal atau AddPassword).

Pandangan AddPassword dan EditPassword berkongsi logik yang hampir sama dan serupa dengan paparan Log Masuk juga. Kedua-duanya tidak membenarkan pengguna memasukkan ruang pada permulaan dan akhir apa yang mereka taip dalam input teks dan mengikut dasar yang sama seperti paparan Log Masuk yang memerlukan kata laluan sekurang-kurangnya 6 aksara ASCII. Pada asasnya, perkara yang membezakan mereka ialah mereka memanggil pautan yang dijana Wails berkaitan dengan tindakan yang perlu mereka lakukan:

/* main.ts */

import { mount } from 'svelte'
import './style.css'
import App from './App.svelte'
import { addMessages, init } from "svelte-i18n"; // ⇐ ⇐
import en from './locales/en.json'; // ⇐ ⇐
import es from './locales/es.json'; // ⇐ ⇐

addMessages('en', en); // ⇐ ⇐
addMessages('es', es); // ⇐ ⇐

init({
  fallbackLocale: 'en', // ⇐ ⇐
  initialLocale: 'en', // ⇐ ⇐
});

const app = mount(App, {
  target: document.getElementById('app')!,
})

export default app

Salin selepas log masuk
Salin selepas log masuk

Paparan lain yang agak rumit ialah Tetapan. Ini mempunyai komponen Bahasa yang menerima sebagai props languageName daripada komponen induknya (Tetapan):

/* frontend/src/locales/en.json */

{
    "language": "Language",
    "app_title": "Nu-i uita • minimalist password store",
    "select_directory": "Select the directory where to save the data export",
    "select_file": "Select the backup file to import",
    "master_password": "Master Password ?",
    "generate": "Generate",
    "insert": "Insert",
    "login": "Login",
    ...
}


/* frontend/src/locales/es.json */

{
    "language": "Idioma",
    "app_title": "Nu-i uita • almacén de contraseñas minimalista",
    "select_directory": "Selecciona el directorio donde guardar los datos exportados",
    "select_file": "Selecciona el archivo de respaldo que deseas importar",
    "master_password": "Contraseña Maestra ?",
    "generate": "Generar",
    "insert": "Insertar",
    "login": "Inciar sesión",
    ...
}

Salin selepas log masuk
Salin selepas log masuk

HTML untuk komponen ini ialah satu pilihan yang mengendalikan pilihan bahasa pengguna. Dalam acara onchange, ia menerima fungsi (handleChange) yang melakukan 3 perkara:

  • menetapkan bahasa pada bahagian hadapan menggunakan perpustakaan svelte-i18n
  • memancarkan peristiwa ("change_titles") supaya masa jalan Wails menukar tajuk bar tajuk aplikasi dan tajuk kotak dialog Select Directory dan Select File yang berkaitan kepada tindakan sebelumnya
  • menyimpan bahasa yang dipilih oleh pengguna dalam DB supaya pada kali seterusnya aplikasi dimulakan ia akan dibuka dengan konfigurasi bahasa tersebut.

Kembali ke paparan Tetapan, keseluruhan operasinya dikawal oleh satu siri acara yang dihantar dan diterima ke atau dari bahagian belakang. Yang paling mudah ialah butang Keluar: apabila pengguna mengklik padanya, acara berhenti dicetuskan dan didengari di bahagian belakang dan aplikasi ditutup (onclick={() => EventsEmit("quit")}). Petua memberitahu pengguna bahawa kekunci Escape (pintasan) melakukan tindakan yang sama, seperti yang telah kami jelaskan.

Butang set semula memanggil fungsi yang memaparkan tetingkap pop timbul:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│   ├── App.svelte
│   ├── assets
│   │   ├── fonts
│   │   │   ├── nunito-v16-latin-regular.woff2
│   │   │   └── OFL.txt
│   │   └── images
│   │       └── logo-universal.png
│   ├── lib
│   │   ├── BackBtn.svelte
│   │   ├── BottomActions.svelte
│   │   ├── EditActions.svelte
│   │   ├── EntriesList.svelte
│   │   ├── Language.svelte
│   │   ├── popups
│   │   │   ├── alert-icons.ts
│   │   │   └── popups.ts
│   │   ├── ShowPasswordBtn.svelte
│   │   └── TopActions.svelte
│   ├── locales
│   │   ├── en.json
│   │   └── es.json
│   ├── main.ts
│   ├── pages
│   │   ├── About.svelte
│   │   ├── AddPassword.svelte
│   │   ├── Details.svelte
│   │   ├── EditPassword.svelte
│   │   ├── Home.svelte
│   │   ├── Login.svelte
│   │   └── Settings.svelte
│   ├── style.css
│   └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │   ├── main
    │   │   ├── App.d.ts
    │   │   └── App.js
    │   └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Jika pengguna menerima tindakan, pengikatan Drop dipanggil, yang membersihkan semua koleksi dalam DB, dan jika janji yang dipulangkan diselesaikan, ia menghantar pengguna ke paparan Log Masuk, menunjukkan modal yang menunjukkan kejayaan tindakan.

Dua tindakan lain yang kekal adalah serupa antara satu sama lain, jadi mari lihat Import Data.

Jika pengguna mengklik pada butang yang sepadan, acara dipancarkan (onclick={() => EventsEmit("import_data")}) yang didengari di bahagian belakang. Apabila diterima, kotak dialog Select File asli dibuka untuk membolehkan pengguna memilih fail sandaran. Jika pengguna memilih fail, pembolehubah yang mengandungi laluan (Lokasi fail) tidak akan mengandungi rentetan kosong dan ini akan mencetuskan peristiwa di bahagian belakang ("enter_password") yang kini didengari di bahagian hadapan untuk, seterusnya, memaparkan a tetingkap pop timbul baharu meminta kata laluan induk yang digunakan semasa eksport dibuat. Sekali lagi, bahagian hadapan akan mengeluarkan satu lagi peristiwa ("kata laluan") yang membawa kata laluan induk yang dimasukkan oleh pengguna. Peristiwa baharu ini, apabila diterima di bahagian belakang, melaksanakan kaedah ImportDump bagi pakej Db yang melaksanakan kerja membaca dan memulihkan data dalam DB daripada fail sandaran yang telah dipilih oleh pengguna. Akibatnya, acara baharu ("data_import") dipancarkan, yang membawa hasil (berjaya atau tidak berjaya) pelaksanaannya sebagai data yang dilampirkan. Bahagian hadapan, apabila menerima acara, hanya perlu melaksanakan 2 tugasan:

  • jika hasilnya berjaya, tetapkan bahasa yang telah disimpan dalam fail sandaran dan tunjukkan modal yang menunjukkan kejayaan tindakan
  • jika atas sebab apa pun import tidak dapat dilakukan, tunjukkan ralat dan puncanya.

Semua ini lebih mudah dilihat dalam logik kod daripada menerangkan dengan perkataan ?:

...
.
├── index.html
├── package.json
├── package.json.md5
├── package-lock.json
├── postcss.config.js
├── README.md
├── src
│   ├── App.svelte
│   ├── assets
│   │   ├── fonts
│   │   │   ├── nunito-v16-latin-regular.woff2
│   │   │   └── OFL.txt
│   │   └── images
│   │       └── logo-universal.png
│   ├── lib
│   │   ├── BackBtn.svelte
│   │   ├── BottomActions.svelte
│   │   ├── EditActions.svelte
│   │   ├── EntriesList.svelte
│   │   ├── Language.svelte
│   │   ├── popups
│   │   │   ├── alert-icons.ts
│   │   │   └── popups.ts
│   │   ├── ShowPasswordBtn.svelte
│   │   └── TopActions.svelte
│   ├── locales
│   │   ├── en.json
│   │   └── es.json
│   ├── main.ts
│   ├── pages
│   │   ├── About.svelte
│   │   ├── AddPassword.svelte
│   │   ├── Details.svelte
│   │   ├── EditPassword.svelte
│   │   ├── Home.svelte
│   │   ├── Login.svelte
│   │   └── Settings.svelte
│   ├── style.css
│   └── vite-env.d.ts
├── svelte.config.js
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── wailsjs
    ├── go
    │   ├── main
    │   │   ├── App.d.ts
    │   │   └── App.js
    │   └── models.ts
    └── runtime
        ├── package.json
        ├── runtime.d.ts
        └── runtime.js

...
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Perlu dinyatakan bahawa fungsi masa jalan Wails yang mendaftarkan pendengar pada bahagian hadapan (EventsOn) mengembalikan fungsi, yang apabila dipanggil membatalkan pendengar tersebut. Adalah mudah untuk membatalkan pendengar tersebut apabila komponen dimusnahkan. Begitu juga dengan React cangkuk onMount boleh "membersihkan" kata pendengar dengan membuat mereka mengembalikan fungsi pembersihan yang, dalam kes ini, akan memanggil semua fungsi yang dikembalikan oleh EventsOn bahawa kami telah mengambil langkah berjaga-jaga untuk menyimpan secara berasingan pembolehubah:

// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {models} from '../models';

export function AddPasswordEntry(arg1:string,arg2:string,arg3:string):Promise<string>;

export function CheckMasterPassword(arg1:string):Promise<boolean>;

export function DeleteEntry(arg1:string):Promise<void>;

export function Drop():Promise<void>;

export function GetAllEntries():Promise<Array<models.PasswordEntry>>;

export function GetEntryById(arg1:string):Promise<models.PasswordEntry>;

export function GetLanguage():Promise<string>;

export function GetMasterPassword():Promise<boolean>;

export function GetPasswordCount():Promise<number>;

export function SaveLanguage(arg1:string):Promise<void>;

export function SaveMasterPassword(arg1:string):Promise<string>;

export function UpdateEntry(arg1:models.PasswordEntry):Promise<boolean>;
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Untuk menyelesaikan semakan bahagian hadapan aplikasi kami ini, ia hanya tinggal untuk menyatakan sesuatu tentang komponen Perihal. Ini mempunyai sedikit logik kerana ia terhad kepada memaparkan maklumat tentang aplikasi seperti biasa dalam kira-kira. Walau bagaimanapun, harus dikatakan bahawa, seperti yang kita lihat, paparan menunjukkan pautan ke repositori aplikasi. Jelas sekali, dalam halaman web biasa teg sauh () akan membuatkan kami menavigasi ke pautan yang sepadan, tetapi dalam aplikasi desktop ini tidak akan berlaku jika Wails tidak mempunyai fungsi tertentu (BrowserOpenURL) untuk ini dalam masa jalannya :

/* package.json */
...
},
  "dependencies": {
    "svelte-copy": "^2.0.0",
    "svelte-i18n": "^4.0.1",
    "svelte-spa-router": "^4.0.1",
    "sweetalert2": "^11.14.5"
  }
...

Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Ini akan membina binari ke dalam folder bina/bin. Walau bagaimanapun, untuk memilih pilihan binaan lain atau melaksanakan penyusunan silang, anda mungkin ingin melihat dokumentasi Wails CLI.

Untuk aplikasi ini, saya rasa saya sudah menyebutnya dalam bahagian pertama siri ini, saya hanya menumpukan pada kompilasi untuk Windows dan Linux. Untuk melaksanakan tugasan ini (yang, kerana ujian, adalah berulang) dengan cara yang selesa, saya telah mencipta beberapa skrip kecil dan Makefile yang "menyelaraskan" mereka.

Arahan make create-bundles mencipta untuk versi Linux fail termampat .tar.xz dengan aplikasi dan Makefile yang bertindak sebagai 'pemasang' yang memasang boleh laku, entri desktop untuk mencipta entri dalam Menu Mula dan ikon aplikasi yang sepadan. Untuk versi Windows, binari hanya dimampatkan sebagai .zip di dalam folder yang dipanggil dist/.Walau bagaimanapun, jika anda lebih suka binaan automatik merentas platform, Wails mempunyai Tindakan Github yang membolehkan anda memuat naik (pilihan lalai) artifak yang dijana ke repositori anda.

Perhatikan bahawa jika anda menggunakan arahan make create-bundles semasa menjalankannya, ia akan memanggil arahan Wails wails build -clean -upx (dalam kes Linux) atau wails build -skipbindings -s -platform windows/amd64 - upx (dalam kes Windows). Bendera -upx merujuk kepada pemampatan binari menggunakan utiliti UPX yang sepatutnya anda pasang pada komputer anda. Sebahagian daripada rahsia saiz kecil boleh laku adalah disebabkan kerja pemampatan hebat yang dilakukan oleh utiliti ini.

Akhir sekali, ambil perhatian bahawa skrip binaan secara automatik menambah teg repositori semasa pada paparan Perihal dan selepas binaan memulihkan nilainya kepada lalai (DEV_VERSION).

Fuh! 2 jawatan ini akhirnya menjadi lebih panjang daripada yang saya fikirkan! Tetapi saya harap anda menyukainya dan, terutamanya, mereka membantu anda memikirkan projek baharu. Mempelajari sesuatu dalam pengaturcaraan berfungsi seperti itu…

Ingat bahawa anda boleh menemui semua kod aplikasi dalam repositori GitHub ini.

Saya pasti saya akan melihat anda dalam siaran lain. Selamat mengekod?!!

Atas ialah kandungan terperinci Apl desktop pengurus kata laluan minimalis: pencerobohan ke dalam rangka kerja Golang's Wails (Bahagian 2). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan