clan-app: Add webview hot-reloading #1724

Merged
clan-bot merged 2 commits from Qubasa/clan-core:Qubasa-main into main 2024-07-09 14:00:11 +00:00
7 changed files with 87 additions and 16 deletions

View File

@ -1,4 +1,35 @@
# clan app
Sure, here's an improved version of your README:
# Clan App
A powerful application that allows users to create and manage their own clans.
## Getting Started
Follow the instructions below to set up your development environment and start the application.
1. **Navigate to the Webview UI Directory:**
Go to the `clan-core/pkgs/webview-ui/app` directory and start the web server by executing:
```bash
vite
```
2. **Start the Clan App:**
In the `clan-app` directory, execute the following command:
```bash
clan-app --debug --content-uri http://localhost:3000
```
This will start the application in debug mode and link it to the web server running at `http://localhost:3000`.
# clan app (old)
Provides users with the simple functionality to manage their locally registered clans.

View File

@ -10,6 +10,8 @@ from clan_app.singletons.toast import InfoToast, ToastOverlay
gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
from pathlib import Path
from clan_cli.custom_logger import setup_logging
from gi.repository import Adw, Gdk, Gio, Gtk
@ -47,6 +49,19 @@ class MainApplication(Adw.Application):
None,
)
self.add_main_option(
"content-uri",
GLib.OptionFlags.NONE,
GLib.OptionFlags.NONE,
GLib.OptionArg.STRING,
"set the webview content uri",
None,
)
site_index: Path = (
Path(__file__).parent.parent / Path("clan_app/.webui/index.html")
).resolve()
self.content_uri = f"file://{site_index}"
self.window: MainWindow | None = None
self.connect("activate", self.on_activate)
self.connect("shutdown", self.on_shutdown)
@ -82,13 +97,21 @@ class MainApplication(Adw.Application):
InfoToast("Debug logging enabled").toast, "info.debugging.enabled"
)
if "content-uri" in options:
self.content_uri = options["content-uri"]
log.debug(f"Setting content uri to {self.content_uri}")
args = command_line.get_arguments()
self.activate()
# Check if there are arguments that are not inside the options
if len(args) > 1:
uri = args[1]
self.emit("join_request", uri)
non_option_args = [arg for arg in args[1:] if arg not in options.values()]
if non_option_args:
uri = non_option_args[0]
self.emit("join_request", uri)
return 0
def on_window_hide_unhide(self, *_args: Any) -> None:
@ -106,7 +129,9 @@ class MainApplication(Adw.Application):
def on_activate(self, source: "MainApplication") -> None:
if not self.window:
self.init_style()
self.window = MainWindow(config=ClanConfig(initial_view="webview"))
self.window = MainWindow(
config=ClanConfig(initial_view="webview", content_uri=self.content_uri)
)
self.window.set_application(self)
self.window.show()

View File

@ -8,3 +8,4 @@ gi.require_version("Gtk", "4.0")
@dataclass
class ClanConfig:
initial_view: str
content_uri: str

View File

@ -1,7 +1,6 @@
import dataclasses
import json
import logging
import sys
import threading
from collections.abc import Callable
from dataclasses import fields, is_dataclass
@ -18,10 +17,6 @@ gi.require_version("WebKit", "6.0")
from gi.repository import Gio, GLib, Gtk, WebKit
site_index: Path = (
Path(sys.argv[0]).absolute() / Path("../..") / Path("clan_app/.webui/index.html")
).resolve()
log = logging.getLogger(__name__)
@ -201,7 +196,7 @@ def from_dict(t: type, data: dict[str, Any] | None) -> Any:
class WebView:
def __init__(self, methods: dict[str, Callable]) -> None:
def __init__(self, content_uri: str, methods: dict[str, Callable]) -> None:
self.method_registry: dict[str, Callable] = methods
self.webview = WebKit.WebView()
@ -217,7 +212,7 @@ class WebView:
self.manager.register_script_message_handler("gtk")
self.manager.connect("script-message-received", self.on_message_received)
self.webview.load_uri(f"file://{site_index}")
self.webview.load_uri(content_uri)
# global mutex lock to ensure functions run sequentially
self.mutex_lock = Lock()

View File

@ -54,7 +54,7 @@ class MainWindow(Adw.ApplicationWindow):
# Override platform specific functions
API.register(open_file)
webview = WebView(methods=API._registry)
webview = WebView(methods=API._registry, content_uri=config.content_uri)
stack_view.add_named(webview.get_webview(), "webview")
stack_view.set_visible_child_name(config.initial_view)

View File

@ -61,9 +61,7 @@ mkShell {
export PYTHONPATH="$GIT_ROOT/pkgs/clan-cli":"$PYTHONPATH"
# Add the webview-ui to the .webui directory
rm -rf ./clan_app/.webui/*
mkdir -p ./clan_app/.webui
cp -a ${webview-ui}/lib/node_modules/@clan/webview-ui/dist/* ./clan_app/.webui
chmod -R +w ./clan_app/.webui
ln -nsf ${webview-ui}/lib/node_modules/@clan/webview-ui/dist/ ./clan_app/.webui
'';
}

View File

@ -32,6 +32,27 @@
self'.devShells.default
];
shellHook = ''
export GIT_ROOT="$(git rev-parse --show-toplevel)"
export PKG_ROOT="$GIT_ROOT/pkgs/webview-ui"
export NODE_PATH="$PKG_ROOT/app/node_modules"
export PATH="$NODE_PATH/.bin:$PATH"
# Define the yellow color code
YELLOW='\033[1;33m'
# Define the reset color code
NC='\033[0m'
# Check if the directory does not exist
if [ ! -d "$PKG_ROOT/app/node_modules" ]; then
echo -e "$YELLOW The directory $PKG_ROOT/app/node_modules does not exist.$NC"
echo -e "$YELLOW Please run 'npm install' in the app directory.$NC"
echo -e "$YELLOW This will install the necessary dependencies.$NC"
echo -e "$YELLOW To serve the webview run 'vite'.$NC"
else
echo "The directory $PKG_ROOT/app/node_modules exists."
fi
mkdir -p ./app/api
cat ${config.packages.clan-ts-api} > ./app/api/index.ts
'';