feat(ui): use correct username on welcome screen (#2050)

* wip

* fetch and use username
This commit is contained in:
Ellie Huxtable 2024-05-28 14:54:05 +01:00 committed by GitHub
parent 43fb9ca745
commit fc4dfe4fff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 304 additions and 39 deletions

200
ui/backend/Cargo.lock generated
View File

@ -201,6 +201,12 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "atomic-write-file"
version = "0.1.4"
@ -217,7 +223,7 @@ version = "18.2.0"
dependencies = [
"async-trait",
"atuin-common",
"base64 0.21.7",
"base64 0.22.1",
"clap",
"config",
"crypto_secretbox",
@ -296,7 +302,7 @@ dependencies = [
"async-trait",
"atuin-client",
"atuin-common",
"base64 0.21.7",
"base64 0.22.1",
"crossterm",
"directories",
"eyre",
@ -1053,6 +1059,12 @@ dependencies = [
"syn 2.0.61",
]
[[package]]
name = "data-url"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
[[package]]
name = "der"
version = "0.7.9"
@ -1908,6 +1920,25 @@ dependencies = [
"tracing",
]
[[package]]
name = "h2"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab"
dependencies = [
"atomic-waker",
"bytes",
"fnv",
"futures-core",
"futures-sink",
"http 1.1.0",
"indexmap 2.2.6",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -2079,7 +2110,7 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-util",
"h2",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
@ -2102,6 +2133,7 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2 0.4.5",
"http 1.1.0",
"http-body 1.0.0",
"httparse",
@ -2121,9 +2153,26 @@ dependencies = [
"futures-util",
"http 0.2.12",
"hyper 0.14.28",
"rustls",
"rustls 0.21.12",
"tokio",
"tokio-rustls",
"tokio-rustls 0.24.1",
]
[[package]]
name = "hyper-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
dependencies = [
"futures-util",
"http 1.1.0",
"hyper 1.3.1",
"hyper-util",
"rustls 0.22.4",
"rustls-pki-types",
"tokio",
"tokio-rustls 0.25.0",
"tower-service",
]
[[package]]
@ -3648,11 +3697,11 @@ dependencies = [
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"h2 0.3.26",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.28",
"hyper-rustls",
"hyper-rustls 0.24.2",
"ipnet",
"js-sys",
"log",
@ -3660,16 +3709,16 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls",
"rustls 0.21.12",
"rustls-native-certs",
"rustls-pemfile",
"rustls-pemfile 1.0.4",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"system-configuration",
"tokio",
"tokio-rustls",
"tokio-rustls 0.24.1",
"tower-service",
"url",
"wasm-bindgen",
@ -3686,12 +3735,15 @@ checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
dependencies = [
"base64 0.22.1",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2 0.4.5",
"http 1.1.0",
"http-body 1.0.0",
"http-body-util",
"hyper 1.3.1",
"hyper-rustls 0.26.0",
"hyper-util",
"ipnet",
"js-sys",
@ -3700,11 +3752,16 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls 0.22.4",
"rustls-pemfile 2.1.2",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"system-configuration",
"tokio",
"tokio-rustls 0.25.0",
"tokio-util",
"tower-service",
"url",
@ -3712,6 +3769,7 @@ dependencies = [
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"webpki-roots 0.26.1",
"winreg 0.52.0",
]
@ -3797,10 +3855,24 @@ checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
dependencies = [
"log",
"ring",
"rustls-webpki",
"rustls-webpki 0.101.7",
"sct",
]
[[package]]
name = "rustls"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
dependencies = [
"log",
"ring",
"rustls-pki-types",
"rustls-webpki 0.102.4",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.6.3"
@ -3808,7 +3880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
dependencies = [
"openssl-probe",
"rustls-pemfile",
"rustls-pemfile 1.0.4",
"schannel",
"security-framework",
]
@ -3822,6 +3894,22 @@ dependencies = [
"base64 0.21.7",
]
[[package]]
name = "rustls-pemfile"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
dependencies = [
"base64 0.22.1",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
@ -3832,6 +3920,17 @@ dependencies = [
"untrusted",
]
[[package]]
name = "rustls-webpki"
version = "0.102.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.16"
@ -4014,18 +4113,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.200"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f"
checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.200"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb"
checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
dependencies = [
"proc-macro2",
"quote",
@ -4410,8 +4509,8 @@ dependencies = [
"once_cell",
"paste",
"percent-encoding",
"rustls",
"rustls-pemfile",
"rustls 0.21.12",
"rustls-pemfile 1.0.4",
"serde",
"serde_json",
"sha2",
@ -4424,7 +4523,7 @@ dependencies = [
"tracing",
"url",
"uuid",
"webpki-roots",
"webpki-roots 0.25.4",
]
[[package]]
@ -4943,6 +5042,46 @@ dependencies = [
"walkdir",
]
[[package]]
name = "tauri-plugin-fs"
version = "2.0.0-beta.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35377195c6923beda5f29482a16b492d431de964389fca9aaf81a0f7e908023f"
dependencies = [
"anyhow",
"glob",
"schemars",
"serde",
"serde_json",
"serde_repr",
"tauri",
"tauri-plugin",
"thiserror",
"url",
"uuid",
]
[[package]]
name = "tauri-plugin-http"
version = "2.0.0-beta.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec2c535106b7a8c2e7c5abdb4b81568b185f0b00bb0d64c37e06a5f0a9729155"
dependencies = [
"data-url",
"http 1.1.0",
"regex",
"reqwest 0.12.4",
"schemars",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"tauri-plugin-fs",
"thiserror",
"url",
"urlpattern",
]
[[package]]
name = "tauri-plugin-sql"
version = "2.0.0-beta.4"
@ -5192,7 +5331,18 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
"rustls",
"rustls 0.21.12",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
dependencies = [
"rustls 0.22.4",
"rustls-pki-types",
"tokio",
]
@ -5445,6 +5595,7 @@ dependencies = [
"syntect",
"tauri",
"tauri-build",
"tauri-plugin-http",
"tauri-plugin-sql",
"time",
"uuid",
@ -5831,6 +5982,15 @@ version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "webpki-roots"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "webview2-com"
version = "0.30.0"

View File

@ -24,6 +24,7 @@ serde_json = "1.0"
time = "0.3.36"
uuid = "1.7.0"
syntect = "5.2.0"
tauri-plugin-http = "2.0.0-beta"
[dependencies.sqlx]
version = "=0.7.3"

View File

@ -13,7 +13,11 @@
"tray:default",
"sql:allow-load",
"sql:allow-execute",
"sql:allow-select"
"sql:allow-select",
{
"identifier": "http:default",
"allow": ["https://api.atuin.sh/*"]
}
],
"platforms": ["linux", "macOS", "windows", "android", "iOS"]
}

View File

@ -75,6 +75,11 @@ async fn config() -> Result<Settings, String> {
Settings::new().map_err(|e| e.to_string())
}
#[tauri::command]
async fn session() -> Result<String, String> {
Settings::new().map_err(|e|e.to_string())?.session_token().map_err(|e|e.to_string())
}
#[tauri::command]
async fn home_info() -> Result<HomeInfo, String> {
let settings = Settings::new().map_err(|e| e.to_string())?;
@ -85,7 +90,7 @@ async fn home_info() -> Result<HomeInfo, String> {
let client = atuin_client::api_client::Client::new(
&settings.sync_address,
&settings.session_token,
settings.session_token().map_err(|e|e.to_string())?.as_str(),
settings.network_connect_timeout,
settings.network_timeout,
)
@ -132,6 +137,7 @@ fn main() {
aliases,
home_info,
config,
session,
dotfiles::aliases::import_aliases,
dotfiles::aliases::delete_alias,
dotfiles::aliases::set_alias,
@ -140,6 +146,7 @@ fn main() {
dotfiles::vars::set_var,
])
.plugin(tauri_plugin_sql::Builder::default().build())
.plugin(tauri_plugin_http::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@ -18,6 +18,7 @@
"@tanstack/react-table": "^8.15.3",
"@tanstack/react-virtual": "^3.5.0",
"@tauri-apps/api": "2.0.0-beta.7",
"@tauri-apps/plugin-http": "2.0.0-beta.3",
"@tauri-apps/plugin-sql": "2.0.0-beta.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",

View File

@ -29,6 +29,9 @@ dependencies:
'@tauri-apps/api':
specifier: 2.0.0-beta.7
version: 2.0.0-beta.7
'@tauri-apps/plugin-http':
specifier: 2.0.0-beta.3
version: 2.0.0-beta.3
'@tauri-apps/plugin-sql':
specifier: 2.0.0-beta.2
version: 2.0.0-beta.2
@ -1338,6 +1341,11 @@ packages:
resolution: {integrity: sha512-KnPRCkQTyqhanNC0K63GBG3wA8I+D1fQuVnAvcBF8f13akOKeQp1gSbu6f77zCxhEk727iV5oQnbHLYzHrECLg==}
dev: false
/@tauri-apps/api@2.0.0-beta.11:
resolution: {integrity: sha512-wJRY+fBUm3KpqZDHMIz5HRv+1vlnvRJ/dFxiyY3NlINTx2qXqDou5qWYcP1CuZXsd39InWVPV3FAZvno/kGCkA==}
engines: {node: '>= 18', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
dev: false
/@tauri-apps/api@2.0.0-beta.4:
resolution: {integrity: sha512-Nxtj28NYUo5iwYkpYslxmOPkdI2WkELU2e3UH9nbJm9Ydki2CQwJVGQxx4EANtdZcMNsEsUzRqaDTvEUYH1l6w==}
engines: {node: '>= 18', npm: '>= 6.6.0', yarn: '>= 1.19.1'}
@ -1455,6 +1463,12 @@ packages:
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-beta.2
dev: true
/@tauri-apps/plugin-http@2.0.0-beta.3:
resolution: {integrity: sha512-TsSFQje2F3Sy5FYuOV+TcgtlvpO9FVdODGT/dJQa+kq/a8Ocel6V57Emj2FiCIyhOJ84us+MiMbQWR1GTfa+mQ==}
dependencies:
'@tauri-apps/api': 2.0.0-beta.11
dev: false
/@tauri-apps/plugin-sql@2.0.0-beta.2:
resolution: {integrity: sha512-gNX/4VjGl0TD4Ct58ar4bLF82iRp2L5sS79FmtzKlXYj7tVbkxenIi+mGIBz3Ut1JQP5WNL4/5wq74bkDlBggA==}
dependencies:

View File

@ -1,5 +1,9 @@
import { Highlight, themes } from "prism-react-renderer";
// @ts-ignore
import Prism from "prismjs";
// @ts-ignore
import "prismjs/components/prism-bash";
export default function CodeBlock({ code, language }: any) {
@ -11,7 +15,7 @@ export default function CodeBlock({ code, language }: any) {
prism={Prism}
language={language}
>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
{({ style, tokens, getLineProps, getTokenProps }) => (
<pre style={style} className="p-4 break-words whitespace-pre-wrap">
{tokens.map((line, i) => (
<div key={i} {...getLineProps({ line })} data-vaul-no-drag>

View File

@ -1,4 +1,3 @@
import { useRef } from "react";
import HistoryRow from "./history/HistoryRow";
export default function HistoryList(props: any) {

View File

@ -1,4 +1,3 @@
import { useState } from "react";
import { ArrowPathIcon } from "@heroicons/react/24/outline";
import { MagnifyingGlassIcon } from "@heroicons/react/20/solid";

View File

@ -16,7 +16,7 @@ import { ColumnDef } from "@tanstack/react-table";
import { invoke } from "@tauri-apps/api/core";
import Drawer from "@/components/Drawer";
import { Alias, inspectHistory } from "@/state/models";
import { Alias } from "@/state/models";
import { useStore } from "@/state/store";
function deleteAlias(name: string, refreshAliases: () => void) {

View File

@ -32,7 +32,7 @@ function deleteVar(name: string, refreshVars: () => void) {
function AddVar({ onAdd: onAdd }: { onAdd?: () => void }) {
let [name, setName] = useState("");
let [value, setValue] = useState("");
let [exp, setExport] = useState(false);
let [exp, setExport] = useState<boolean>(false);
// simple form to add vars
return (
@ -85,7 +85,7 @@ function AddVar({ onAdd: onAdd }: { onAdd?: () => void }) {
autoCorrect="off"
spellCheck="false"
type="checkbox"
value={exp}
value={exp.toString()}
onChange={(e) => setExport(e.target.checked)}
/>
Export the var and make it visible to subprocesses

View File

@ -4,7 +4,7 @@ import PacmanLoader from "react-spinners/PacmanLoader";
import CodeBlock from "@/components/CodeBlock";
import HistoryRow from "@/components/history/HistoryRow";
import { inspectCommandHistory } from "@/state/models";
import { ShellHistory, inspectCommandHistory } from "@/state/models";
function renderLoading() {
return (
@ -15,7 +15,7 @@ function renderLoading() {
}
export default function HistoryInspect({ history }: any) {
let [other, setOther] = useState([]);
let [other, setOther] = useState<ShellHistory[]>([]);
useEffect(() => {
(async () => {

View File

@ -3,7 +3,10 @@ import { DateTime } from "luxon";
import { ChevronRightIcon } from "@heroicons/react/20/solid";
import { Highlight, themes } from "prism-react-renderer";
// @ts-ignore
import Prism from "prismjs";
// @ts-ignore
import "prismjs/components/prism-bash";
import Drawer from "../Drawer";
@ -49,7 +52,7 @@ export default function HistoryRow({ h }: any) {
language="bash"
prism={Prism}
>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
{({ style, tokens, getLineProps, getTokenProps }) => (
<pre style={style} className="!bg-inherit text-sm">
{tokens &&
tokens.map((line, i) => {

View File

@ -48,7 +48,7 @@ function TopTable({ stats }: any) {
</tr>
</thead>
<tbody className="divide-y divide-gray-200 bg-white">
{stats.map((stat) => (
{stats.map((stat: any) => (
<tr>
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8">
{stat[0][0]}

View File

@ -43,7 +43,7 @@ function Header({ current, setCurrent }: HeaderProps) {
);
}
function classNames(...classes) {
function classNames(...classes: any[]) {
return classes.filter(Boolean).join(" ");
}

View File

@ -8,9 +8,6 @@ import Drawer from "@/components/Drawer.tsx";
import { useStore } from "@/state/store";
import { inspectHistory, listHistory } from "@/state/models";
import { invoke } from "@tauri-apps/api/core";
function Header() {
return (
<div className="md:flex md:items-center md:justify-between">
@ -66,7 +63,7 @@ export default function Search() {
refreshHistory();
}, []);
const parentRef = useRef();
const parentRef = useRef<HTMLElement | null>(null);
const rowVirtualizer = useVirtualizer({
count: history.length,

View File

@ -15,7 +15,7 @@ function Stats({ stats }: any) {
<dt className="truncate text-sm font-medium text-gray-500">
{item.name}
</dt>
<dd className="mt-1 text-3xl font-semibold tracking-tight text-gray-900">
<dd className="mt-1 text-xl font-semibold tracking-tight text-gray-900">
{item.stat}
</dd>
</div>
@ -44,10 +44,13 @@ function Header({ name }: any) {
export default function Home() {
const homeInfo = useStore((state) => state.homeInfo);
const user = useStore((state) => state.user);
const refreshHomeInfo = useStore((state) => state.refreshHomeInfo);
const refreshUser = useStore((state) => state.refreshUser);
useEffect(() => {
refreshHomeInfo();
refreshUser();
}, []);
if (!homeInfo) {
@ -57,7 +60,7 @@ export default function Home() {
return (
<div className="pl-60">
<div className="p-10">
<Header name={"Ellie"} />
<Header name={user.username} />
<div className="pt-10">
<h2 className="text-xl font-bold">Sync</h2>

13
ui/src/state/client.ts Normal file
View File

@ -0,0 +1,13 @@
// At some point, I'd like to replace some of the Atuin calls
// with separate state handling here
import { invoke } from "@tauri-apps/api/core";
import { Settings } from "@/state/models";
export async function sessionToken(): Promise<String> {
return await invoke("session");
}
export async function settings(): Promise<Settings> {
return await invoke("config");
}

View File

@ -69,6 +69,46 @@ export interface InspectHistory {
other: ShellHistory[];
}
// Not yet complete. Not all types are defined here.
// Gonna hold off until the settings refactoring.
export interface Settings {
auto_sync: boolean;
update_check: boolean;
sync_address: string;
sync_frequency: string;
db_path: string;
record_store_path: string;
key_path: string;
session_path: string;
shell_up_key_binding: boolean;
inline_height: number;
invert: boolean;
show_preview: boolean;
max_preview_height: number;
show_help: boolean;
show_tabs: boolean;
word_chars: string;
scroll_context_lines: number;
history_format: string;
prefers_reduced_motion: boolean;
store_failed: boolean;
secrets_filter: boolean;
workspaces: boolean;
ctrl_n_shortcuts: boolean;
network_connect_timeout: number;
network_timeout: number;
local_timeout: number;
enter_accept: boolean;
smart_sort: boolean;
sync: Sync;
}
interface Sync {
records: boolean;
}
// Define other interfaces (Dialect, Timezone, Style, SearchMode, FilterMode, ExitMode, KeymapMode, CursorStyle, WordJumpMode, RegexSet, Stats) accordingly.
export async function inspectCommandHistory(
h: ShellHistory,
): Promise<InspectHistory> {

View File

@ -1,6 +1,8 @@
import { create } from "zustand";
import { parseISO } from "date-fns";
import { fetch } from "@tauri-apps/plugin-http";
import {
User,
DefaultUser,
@ -9,9 +11,11 @@ import {
Alias,
ShellHistory,
Var,
Settings,
} from "./models";
import { invoke } from "@tauri-apps/api/core";
import { sessionToken, settings } from "./client";
// I'll probs want to slice this up at some point, but for now a
// big blobby lump of state is fine.
@ -26,6 +30,7 @@ interface AtuinState {
refreshHomeInfo: () => void;
refreshAliases: () => void;
refreshVars: () => void;
refreshUser: () => void;
refreshShellHistory: (query?: string) => void;
historyNextPage: (query?: string) => void;
}
@ -81,6 +86,21 @@ export const useStore = create<AtuinState>()((set, get) => ({
});
},
refreshUser: async () => {
let config = await settings();
let session = await sessionToken();
let url = config.sync_address + "/api/v0/me";
let res = await fetch(url, {
headers: {
Authorization: `Token ${session}`,
},
});
let me = await res.json();
set({ user: me });
},
historyNextPage: (query?: string) => {
let history = get().shellHistory;
let offset = history.length - 1;