Adding server url page #23

Merged
tepichord merged 11 commits from issues/10-server-url into main 2026-02-18 17:28:40 -08:00
Collaborator

Closes #10

  • Adds shadcn components needed for basic server connection card
  • Sets up Tauri store on the rust end (copying petite but making it lazier)
  • Adds some commands to get and set the server url
  • Adding SWR and using it to fetch the url on load
  • Upon loading will redirect to home, but there's no way to clear the url value except editing the file manually in AppData/Roaming/systems.graham.microclimate/config.json will need to add a button in settings or maybe just in layout temporarily to change server url
Closes #10 - Adds shadcn components needed for basic server connection card - Sets up Tauri store on the rust end (copying petite but making it lazier) - Adds some commands to get and set the server url - Adding SWR and using it to fetch the url on load - Upon loading will redirect to home, but there's no way to clear the url value except editing the file manually in `AppData/Roaming/systems.graham.microclimate/config.json` will need to add a button in settings or maybe just in layout temporarily to change server url
tepichord force-pushed issues/10-server-url from 18117f25d1 to 570c3d24a0 2026-02-12 13:24:19 -08:00 Compare
Author
Collaborator

"Calling gRPC procedures to connect commit" isn't real, look at the Commits tab for the actual up-to-date commit list

"Calling gRPC procedures to connect commit" isn't real, look at the Commits tab for the actual up-to-date commit list
Author
Collaborator
  • Swapped SWR out for a react-router data loader as I couldn't find a nice way to use SWR without caching the value.
- Swapped SWR out for a react-router data loader as I couldn't find a _nice_ way to use SWR without caching the value.
@ -2,0 +23,4 @@
const navigate = useNavigate();
const [url, setUrl] = useState("");
const { data, error, isLoading } = useSWR("get_server_url", fetcher);
Author
Collaborator
  • Don't pass a cache key, use null as we don't want caching
  • inline the fetcher
  • add return type specifier to fetcher
- Don't pass a cache key, use null as we don't want caching - inline the fetcher - add return type specifier to fetcher
tepichord marked this conversation as resolved
@ -2,0 +25,4 @@
const { data, error, isLoading } = useSWR("get_server_url", fetcher);
// console.log(`"${data}"`, error, isLoading);
Author
Collaborator

Delete

Delete
tepichord marked this conversation as resolved
tepichord force-pushed issues/10-server-url from 0d8400821f to edbf32f37f 2026-02-13 16:08:56 -08:00 Compare
puregarlic requested changes 2026-02-13 20:05:46 -08:00
Dismissed
puregarlic left a comment
Owner

Just a few things to cleanup, in addition to the anyhow comments. I've already discussed ts-rs with @seb, so at the very least we'll want to get that in for complicated commands--though it's not necessarily required for your simple commands at this time though. I'm open to discussion as to how to proceed, but again, my perspective is that there's no time like the present to be thorough about errors.

Just a few things to cleanup, in addition to the `anyhow` comments. I've already discussed `ts-rs` with @seb, so at the very least we'll want to get that in for complicated commands--though it's not necessarily required for your simple commands at this time though. I'm open to discussion as to how to proceed, but again, my perspective is that there's no time like the present to be thorough about errors.
@ -1,1 +6,4 @@
export default function Layout() {
const navigate = useNavigate();
const handleOnClick = async (e: React.SyntheticEvent) => {
Owner

This is a good candidate for a clientAction.

This is a good candidate for a `clientAction`.
@ -2,0 +32,4 @@
const navigate = useNavigate();
const [url, setUrl] = useState("");
const handleSubmit = async (e: React.SyntheticEvent) => {
Owner

This should be a clientAction as well

This should be a `clientAction` as well
@ -28,2 +28,4 @@
tonic-prost = "*"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
tauri-plugin-store = "2"
anyhow = "1.0.101"
Owner

Not gonna lie... Not a huge fan of anyhow. I know it's convenient, but we should start on the right foot of handling our errors correctly.

I know with Tauri commands especially, this is annoying, because the error result needs to derive serde's Serialize. This means:

  1. You often can't return the error directly,
  2. You have to define an extensive Error enum that encompasses all of the possible failures, and then
  3. You don't get decent types in JS land, so you don't even know what the errors are when you need to present them.

I used ts-rs in petite to make this easier. At the module level, you can define a custom error enum that will handle any un-derived errors into strings, with added metadata to describe the practical effect of the error. Then, because that enum is Serialize-able, ts-rs can generate a type you can use in JS land to check for different error conditions. And also--you can now get strongly-typed objects from structs for command payloads.

I know it feels a bit excessive, but I would really us rather get in the habit of handling these errors the right way sooner rather than later.

Not gonna lie... Not a huge fan of `anyhow`. I know it's convenient, but we should start on the right foot of handling our errors correctly. I know with Tauri commands especially, this is annoying, because the error result needs to derive serde's `Serialize`. This means: 1. You often can't return the error directly, 2. You have to define an extensive `Error` enum that encompasses all of the possible failures, and then 3. You don't get decent types in JS land, so you don't even know what the errors are when you need to present them. I used [ts-rs](https://github.com/Aleph-Alpha/ts-rs) in `petite` to make this easier. At the module level, you can define a custom error enum that will handle any un-derived errors into strings, with added metadata to describe the practical effect of the error. Then, because that enum is `Serialize`-able, ts-rs can generate a type you can use in JS land to check for different error conditions. And also--you can now get strongly-typed objects from structs for command payloads. I know it feels a bit excessive, but I would really us rather get in the habit of handling these errors the right way sooner rather than later.
Author
Collaborator

Yeah makes sense, I'll remove anyhow, but custom errors always seem like such a huge waste of time. In the end I've never seen use of custom error types. I always just need the message, and the stack trace. And I hate the effort of elaborating all these different categories of errors and then their use cases just seem unusable because on the receiving end you want to split out error handling based on the category of error but end up doing basically the same thing. After all, what can you really do when there's an error? it's not like the client is gonna fix that.

Griping aside, since tauri::command doesn't even allow anyhow errors it's definitely a non-starter.

Yeah makes sense, I'll remove anyhow, but custom errors always seem like such a huge waste of time. In the end I've never seen use of custom error types. I always just need the message, and the stack trace. And I hate the effort of elaborating all these different categories of errors and then their use cases just seem unusable because on the receiving end you want to split out error handling based on the category of error but end up doing basically the same thing. After all, what can you really do when there's an error? it's not like the client is gonna fix that. Griping aside, since tauri::command doesn't even allow anyhow errors it's definitely a non-starter.
@ -12,0 +24,4 @@
Ok(())
})
.invoke_handler(tauri::generate_handler![
greet,
Owner

We can probably yoink this guy now

We can probably yoink this guy now
tepichord marked this conversation as resolved
Collaborator

Can we merge #24 in here prior to merging to main?

Can we merge #24 in here prior to merging to main?
Owner

@seb wrote in #23 (comment):

Can we merge #24 in here prior to merging to main?

I'm for this. You'll need to coordinate with @tepichord.

@seb wrote in https://git.gloom.garden/puregarlic/microclimate/pulls/23#issuecomment-368: > Can we merge #24 in here prior to merging to main? I'm for this. You'll need to coordinate with @tepichord.
Closes #26.

This PR implements a client for connecting to the channel server, registers it with the AppState, and exposes the behavior through Tauri commands.

Reviewed-on: #24
Reviewed-by: Graham <red.iron2345@fastmail.com>
Co-authored-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
Co-committed-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
tepichord force-pushed issues/10-server-url from 4ddf795f59 to 79a1ca3d88 2026-02-18 16:51:55 -08:00 Compare
puregarlic approved these changes 2026-02-18 16:52:39 -08:00
puregarlic left a comment
Owner

LGTM

LGTM
Closes #7.

Reviewed-on: #33
Reviewed-by: Graham <red.iron2345@fastmail.com>
Co-authored-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
Co-committed-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
puregarlic force-pushed issues/10-server-url from 54a371846d to 4430992f0d 2026-02-18 17:17:19 -08:00 Compare
Sign in to join this conversation.
No description provided.