19 Commits
0.1.0 ... main

Author SHA1 Message Date
0c5cf173a6 Update all non-major dependencies
All checks were successful
Main workflow / Lint code & build (push) Successful in 6m49s
2024-08-24 04:06:18 +00:00
c0eca40382 Update Rust crate serde to v1.0.204
All checks were successful
Main workflow / Lint code & build (push) Successful in 7m0s
2024-07-08 00:07:51 +00:00
bd563c4785 Update Rust crate serde_json to v1.0.120
All checks were successful
Main workflow / Lint code & build (push) Successful in 8m0s
2024-07-01 18:08:02 +00:00
9c29a99731 Update all non-major dependencies
All checks were successful
Main workflow / Lint code & build (push) Successful in 6m15s
2024-06-17 00:07:29 +00:00
0f4fc07416 Update Rust crate wry to v0.40.1
All checks were successful
Main workflow / Lint code & build (push) Successful in 7m18s
2024-06-03 00:07:47 +00:00
989b3af4c1 Update all non-major dependencies
All checks were successful
Main workflow / Lint code & build (push) Successful in 6m16s
2024-05-27 00:05:58 +00:00
d11952525e Update Rust crate serde to v1.0.202
All checks were successful
Main workflow / Lint code & build (push) Successful in 6m17s
2024-05-20 00:06:12 +00:00
6dbadf1e74 Update all non-major dependencies
All checks were successful
Main workflow / Lint code & build (push) Successful in 6m1s
2024-05-13 00:05:33 +00:00
08c28830b0 Update Rust crate serde to v1.0.200
All checks were successful
Main workflow / Lint code & build (push) Successful in 5m44s
2024-05-06 00:05:59 +00:00
f9db7deed1 Update ipc_handler with breaking change
All checks were successful
Main workflow / Lint code & build (push) Successful in 5m23s
2024-04-27 10:48:16 +02:00
2ddc8b9091 Update all non-major dependencies
Some checks failed
Main workflow / Lint code & build (push) Failing after 3m4s
2024-04-27 04:41:03 +00:00
5b10e60102 Enable weekly renovate schedule
All checks were successful
Main workflow / Lint code & build (push) Successful in 5m8s
2024-03-08 10:46:36 +01:00
7b39e2c243 Fix webview after breaking change
All checks were successful
Main workflow / Lint code & build (push) Successful in 5m12s
2024-03-07 11:59:46 +01:00
c9c6477133 Update all non-major dependencies
Some checks failed
Main workflow / Lint code & build (push) Failing after 2m41s
2024-03-07 10:40:56 +00:00
b310d54a43 Add renovate config
All checks were successful
Main workflow / Lint code & build (push) Successful in 6m35s
2024-03-07 11:01:58 +01:00
9014fe3023 Add ci
All checks were successful
Main workflow / Lint code & build (push) Successful in 6m32s
2024-03-07 10:54:05 +01:00
01e9fb4256 Add https:// scheme if url is scheme-less 2024-02-10 18:38:38 +01:00
f74ebb45e1 Add setup page in case base_url is empty 2024-02-10 17:03:46 +01:00
13a2e52f9d Fix quote style in JS 2024-02-10 16:29:31 +01:00
9 changed files with 334 additions and 1004 deletions

66
.github/workflows/main.yaml vendored Normal file
View File

@@ -0,0 +1,66 @@
---
name: Main workflow
on:
push:
jobs:
build:
name: Lint code & build
runs-on: ubuntu-22.04
timeout-minutes: 10
container: alpine:3.19
steps:
- name: Install dependencies
run: |
apk update
apk add \
build-base \
git \
glib-dev \
gtk+3.0-dev \
nodejs \
webkit2gtk-4.1-dev
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup toolchain
uses: actions/rs-toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Get Cargo.lock hash
id: hash
run: |
hash="$(sha256sum Cargo.lock | awk '{print $1}')"
echo "hash=$hash" >>"$GITHUB_OUTPUT"
- name: Setup cache
uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: cargo-${{ steps.hash.outputs.hash }}
- name: Run fmt
run: cargo fmt --all --check
- name: Run check
run: cargo check
- name: Run clippy
run: cargo clippy -- -D warnings
- name: Build
run: cargo build
env:
# Disable static linking; rustup's toolchain enables by default for musl
RUSTFLAGS: -C target-feature=-crt-static

11
.renovaterc.json5 Normal file
View File

@@ -0,0 +1,11 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"dependencyDashboard": true,
"extends": [
":enableVulnerabilityAlerts",
"group:allNonMajor",
"schedule:weekly",
"security:openssf-scorecard",
],
"enabledManagers": ["cargo"],
}

1129
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,10 +5,10 @@ version = "0.1.0"
edition = "2021"
[dependencies]
confy = "0.6.0"
confy = "0.6.1"
dirs = "5.0.1"
eyre = "0.6.12"
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
tao = "0.25.0"
wry = "0.36.0"
serde = { version = "1.0.199", features = ["derive"] }
serde_json = "1.0.116"
tao = "0.29.0"
wry = "0.42.0"

56
html/index.html Normal file
View File

@@ -0,0 +1,56 @@
<html>
<head>
<title>SilverBullet</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
* {
box-sizing: border-box;
}
main {
display: flex;
margin: 0 auto;
align-items: center;
justify-content: center;
min-height: 100vh;
max-width: 768px;
}
input, button {
padding: 10px;
margin: 5px 0;
width: 100%;
}
</style>
</head>
<body>
<main>
<form id="set_url" target="#">
<label for="url"><b>Set your SilverBullet instance</b></label>
<input type="url" id="url" name="url" required autofocus />
<button type="submit">Submit</button>
</form>
</main>
<script>
const form = document.getElementById('set_url');
form.addEventListener('submit', async (e) => {
try {
// Test that the URL is a valid URL.
const url = new URL(form.elements['url'].value);
// Test that the URL resolves to an actual website.
await fetch(url.href, { method: 'HEAD', mode: 'no-cors' });
window.ipc.postMessage(JSON.stringify({ command: 'set_url', url }));
window.location.assign(url);
} catch(e) {
if (e instanceof TypeError) {
// Fetch failed due to network error (dns, etc.)
alert('Failed to connect to SilverBullet due to a network error.\nPlease check that the URL is correct and you are connected.');
} else {
alert('The SilverBullet URL doesn\'t seem to be valid.\nPlease check that the URL is correct.');
}
}
e.preventDefault();
});
</script>
</body>
</html>

View File

@@ -11,7 +11,7 @@ window.addEventListener('load', () => {
if (target.href !== null) {
if (target.host !== window.location.host) {
window.ipc.postMessage(JSON.stringify({
command: "open",
command: 'open',
uri: target.href,
}));
e.preventDefault();

View File

@@ -1,4 +1,4 @@
use eyre::eyre;
use confy::ConfyError;
use serde::{Deserialize, Serialize};
pub const APP_NAME: &str = env!("CARGO_PKG_NAME");
@@ -10,11 +10,11 @@ pub struct Config {
}
impl Config {
pub fn load() -> eyre::Result<Self> {
let cfg: Config = confy::load(APP_NAME, "config")?;
if cfg.base_url.is_empty() {
return Err(eyre!("base_url must not be empty"));
pub fn load() -> Result<Self, ConfyError> {
confy::load(APP_NAME, "config")
}
Ok(cfg)
pub fn store(&self) -> Result<(), ConfyError> {
confy::store(APP_NAME, "config", self)
}
}

View File

@@ -2,10 +2,13 @@ use std::process;
use serde::{Deserialize, Serialize};
use crate::config::Config;
#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "command", rename_all = "lowercase")]
#[serde(tag = "command", rename_all = "snake_case")]
pub enum Command {
Open { uri: String },
SetUrl { url: String },
}
impl Command {
@@ -15,6 +18,12 @@ impl Command {
process::Command::new("xdg-open").arg(uri).output()?;
Ok(())
}
Command::SetUrl { url } => {
let cfg = Config {
base_url: url.to_string(),
};
Ok(cfg.store()?)
}
}
}
}

View File

@@ -15,27 +15,34 @@ pub fn run(cfg: Config) -> eyre::Result<()> {
.with_title("SilverBullet")
.build(&event_loop)?;
let builder = WebViewBuilder::new_gtk(
window
.default_vbox()
.ok_or_else(|| eyre!("failed to get vbox"))?,
);
let data_dir = dirs::state_dir()
.ok_or_else(|| eyre!("failed to find state dir"))?
.join(APP_NAME);
let mut context = WebContext::new(Some(data_dir));
let webview = builder
let mut builder = WebViewBuilder::new_gtk(
window
.default_vbox()
.ok_or_else(|| eyre!("failed to get vbox"))?,
)
.with_initialization_script(include_str!("../js/init.js"))
.with_ipc_handler(|msg| match serde_json::from_str::<Command>(&msg) {
.with_ipc_handler(|req| match serde_json::from_str::<Command>(req.body()) {
Ok(cmd) => cmd
.handle()
.unwrap_or_else(|err| eprintln!("failed to handle command: {err}")),
Err(err) => eprintln!("invalid ipc command {msg}: {err}"),
Err(err) => eprintln!("invalid ipc command {}: {err}", req.body()),
})
.with_web_context(&mut context)
.with_url(&cfg.base_url)?
.build()?;
.with_web_context(&mut context);
if cfg.base_url.is_empty() {
builder = builder.with_html(include_str!("../html/index.html"));
} else {
let mut base_url = cfg.base_url;
if !(base_url.starts_with("http://") || base_url.starts_with("https://")) {
base_url.insert_str(0, "https://");
}
builder = builder.with_url(&base_url);
}
let webview = builder.build()?;
let mut modifiers = ModifiersState::default();
event_loop.run(move |event, _, control_flow| {