Zephyrnet-logo

Hoe ik de Focus-app heb gemaakt met React en Rust

Datum:

Hallo ๐Ÿ‘‹,

In dit artikel zal ik de stappen beschrijven die ik heb doorlopen om een โ€‹โ€‹kleine desktop-applicatie te maken waarmee ik me kan concentreren op mijn dagelijkse taken.

Een van mijn doelen is om de ultieme tijdmanagementtool te creรซren die al mijn productiviteitsproblemen zal oplossen, maar laten we voor nu beginnen met een klein probleem.
Wanneer ik aan een taak werk, word ik vaak onderbroken door andere taken die gedaan moeten worden (er wordt me een nieuwe taak toegewezen, ik herinner me iets dat ik zou moeten doen, โ€ฆ), meestal is de nieuwe taak niet urgent en kan wachten tot ik mijn huidige af heb. Maar ik word erdoor afgeleid en soms merk ik dat ik er prioriteit aan geef boven de huidige taak, alleen om het niet te vergeten. Dan wordt het hervatten van de oorspronkelijke taak moeilijk omdat ik de focus verloor. Om dit probleem op te lossen, had ik een manier nodig om snel onderbrekende taken te loggen wanneer ze opduiken en ze te vergeten totdat ik mijn huidige taak heb voltooid.

  • Ik ben ergens mee bezig โ€ฆ er verschijnt een storend idee/taak.
  • Ik druk op een aangepaste snelkoppeling op mijn toetsenbord en er verschijnt een tekstinvoer in het midden van het scherm.
  • Ik typ een korte beschrijving van het onderbrekende idee/de taak, druk op enter en de tekstinvoer verdwijnt.
  • Ik zet mijn werk normaal voort.
    ...
  • Als ik klaar ben, open ik een vooraf gedefinieerd bestand en vind ik alle ideeรซn/taken die ik erin heb getypt.

Wat ik hier probeer te bouwen is een desktop-applicatie, maar ik wil webtechnologieรซn gebruiken (althans voor de gebruikersinterface). De populaire tool om dat te doen is Elektron, maar ik ben onlangs begonnen met het leren van Rust en Tauri lijkt me een goed hulpmiddel om te proberen. Dus ik zal het gebruiken met React voor de frontend en Tailwind voor styling.

Ik volgde de instructies op Tauri's vereistenpagina om Rust en Node op mijn systeem in te stellen, dan ren ik yarn create tauri-app om het project te maken. Ik heb het project een naam gegeven focus en koos de create-vite ontvangstbewijs voor de gebruikersinterface en stemde ermee in om te installeren @tauri-apps/api. Kies dan voor de react-ts sjabloon van create-vite:

1-create-project.gif

Tauri heeft het project gemaakt en de afhankelijkheden geรฏnstalleerd. Laten we eens kijken naar de bestandsstructuur:

src/ main.tsx <- entry point of JS/TS ... other UI files here
src-tauri/ icons/ <- icons of different sizes src/ main.rs <- entry point for the application target/ <- the compiled and bundles files Cargo.toml <- like package.json for Rust Cargo.lock <- like yarn.lock tauri.conf.json <- config file for Tauri
index.html <- entry point of the UI
package.json
yarn.lock
tsconfig.json
vite.config.ts <- config file for Vite

Nu draait de yarn tauri dev moet de app starten. Dit zal even duren aangezien Rust de code voor de eerste keer compileert, de volgende uitvoeringen zullen snel zijn.

De laatste stap van de installatie was om Tailwind aan het project toe te voegen, dat deed ik door te volgen de officiรซle documenten

Voor de gebruikersinterface heb ik alleen een tekstinvoer nodig waarin ik de taak typ en vervolgens op Enter druk om deze op te slaan. Dus ik veranderde de App componentcode naar het volgende:

function App() { return <input type="text" className="w-[800px] h-[80px] bg-[#222] text-2xl text-white px-6" />
}

Merk op dat ik Tailwind's gebruik willekeurige waarden syntaxis om een โ€‹โ€‹donkergrijs te hebben 800px/80px invoer.

Wanneer ik wat tekst typ in deze invoer, druk dan op Enter, Ik wil dat die tekst ergens aan een bestand wordt toegevoegd. Laten we beginnen met het opslaan van de tekst in een staat en het loggen wanneer Enter wordt ingedrukt:

function App() { const [content, setContent] = React.useState('') return ( <input type="text" value={content} onChange={e => setContent(e.target.value)} onKeyDown={e => e.key === 'Enter' && console.log(content)} className="w-[800px] h-[80px] bg-[#222] text-2xl text-white px-6" /> )
}

2-add-state.gif

De volgende stap is het schrijven van een Rust-functie die de invoerinhoud ontvangt en aan een bestand toevoegt. Na het lezen van de Roest bellen vanaf de frontend documentatiepagina, heb ik de src-tauri/src/main.rs Naar het volgende:

Waarschuwing: ik ben nieuw bij Rust, dus het kan zijn dat ik veel dingen fout doe in deze code

#![cfg_attr( all(not(debug_assertions), target_os = "windows"), windows_subsystem = "windows"
)] use std::fs::OpenOptions;
use std::io::prelude::*; #[tauri::command]
fn add_task(content: String) { let mut file = OpenOptions::new() .create(true) .append(true) .open("../tasks.txt") .expect("Error while opening the tasks file"); writeln!(file, "{}", content).expect("Error while writing in the tasks file");
} fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![add_task]) .run(tauri::generate_context!()) .expect("error while running tauri application");
}

Daarna heb ik de App component om die functie wanneer aan te roepen Enter wordt ingedrukt:

function App() { const [content, setContent] = React.useState('') const handleKeyDown = async (e: React.KeyboardEvent) => { if (e.key === 'Enter') { await invoke('add_task', { content }) } } return ( <input type="text" value={content} onChange={e => setContent(e.target.value)} onKeyDown={handleKeyDown} className="w-[800px] h-[80px] bg-[#222] text-2xl text-white px-6" /> )
}

Nu bij het typen van wat tekst en slaan Enter, wordt de ingevoerde tekst toegevoegd aan het tasks.txt bestand.

3-toevoegen-aan-bestand.gif

Merk op dat dit bestand wordt gemaakt in de hoofdmap van het project terwijl het pad in de Rust-code is ../tasks.txt, dit komt omdat de app wordt uitgevoerd in de src-tauri directory, dus elk relatief pad is relatief ten opzichte van die directory. Het is beter om een โ€‹โ€‹absoluut pad te gebruiken en dit door de gebruiker te laten definiรซren. De gemakkelijkste manier die ik kon bedenken om het te definiรซren, is via een omgevingsvariabele, laten we het noemen FOCUS_TASKS_PATH.

Dus heb ik deze variabele toegevoegd aan my .zshrc vervolgens de Rust-code bijgewerkt:


use std::env; #[tauri::command]
fn add_task(content: String) { let path = env::var("FOCUS_TASKS_PATH") .expect("The 'FOCUS_TASKS_PATH' env variable was not found!"); let mut file = OpenOptions::new() .create(true) .append(true) .open(path) .expect("Error while opening the tasks file"); writeln!(file, "{}", content).expect("Error while writing in the tasks file")
}

Het oorspronkelijke idee was om een โ€‹โ€‹pop-up te hebben, zoiets als Spotlight op macOS, maar wat we nu hebben in een browservenster! Gelukkig stelt Tauri ons in staat om het venster aan te passen met behulp van de src-tauri/tauri.conf.json bestand. De initiรซle vensterconfiguratie was:

{ "fullscreen": false, "height": 600, "resizable": true, "title": "Focus", "width": 800
}

Ik heb het vervangen door

{ "fullscreen": false, "width": 800, "height": 80, "title": "Focus", "resizable": false, "center": true, "decorations": false }

Het resultaat ziet er goed uit ????

4-pop-up.gif

Nu wil ik dat de pop-up verdwijnt als ik druk Enter, dus laten we een toevoegen process.exit() in onze App component (dit kan ook worden toegevoegd aan het add_task Roestfunctie).

import { process } from '@tauri-apps/api' function App() { const [content, setContent] = React.useState('') const handleKeyDown = async (e: React.KeyboardEvent) => { if (e.key === 'Enter') { await invoke('add_task', { content }) process.exit() } } }

Nu wordt de pop-up gesloten wanneer Enter wordt ingedrukt ????

Ik denk dat we de alfaversie van de applicatie nu klaar hebben, laten we hem bouwen

yarn tauri build

Eerst mislukte de opdracht met dit bericht

Error You must change the bundle identifier in `tauri.conf.json > tauri > bundle > identifier`. The default value `com.tauri.dev` is not allowed as it must be unique across applications.

De identificatie instellen op dev.webneat.focus probleem opgelost.

De compilatie duurde even en toen had ik de volgende bestanden gegenereerd (ik gebruik Ubuntu):

src-tauri/target/release/bundle/ deb/focus_0.1.0_amd64.deb appimage/focus_0.1.0_amd64.AppImage

Omdat de AppImage gemakkelijker te gebruiken is (geen installatie nodig), heb ik hem zojuist verplaatst naar mijn bin directory en noemde het focus:

sudo mv src-tauri/target/release/bundle/appimage/focus_0.1.0_amd64.AppImage /usr/bin/focus

Door nu de opdracht focus op de terminal uit te voeren, wordt de pop-up geopend ????

Op Ubuntu kan ik een nieuwe aangepaste snelkoppeling instellen op de toetsenbordinstellingen. Als ik nu ergens op die snelkoppeling druk, verschijnt de pop-up, typ ik wat ik in gedachten heb en druk ik op Enter ga dan verder met waar ik mee bezig was ๐ŸŽ‰

Bekijk de repository hier https://github.com/webNeat/focus

spot_img

Laatste intelligentie

spot_img