Compare commits

...
5 Commits
10 changed files with 123 additions and 12 deletions
@@ -0,0 +1,13 @@
{
"build": {
"frontendDist": "../../../frontend/apps/artcraft/dist",
"beforeDevCommand": "echo 'this is static development; no live reload'",
"beforeBuildCommand": "echo 'this is static development; no live reload'",
"devUrl": null
},
"app": {
"withGlobalTauri": true,
"windows": [
]
}
}
@@ -18,9 +18,9 @@ const billingTabs = [
const pricingConfig = {
header: {
title: "Purchase a subscription",
title: "Subscribe to ArtCraft",
subtitle:
"Upgrade to gain access to Pro features and generate more, faster.",
"Support ArtCraft development and get generation credits without having to add 3rd party services.",
},
yearlyDiscount: 20,
};
@@ -10,7 +10,13 @@ export function ArtcraftBillingBlock({
<div className="w-full">
<PricingContent
title="Video Generation is Resource Intensive"
subtitle="Creating high-quality videos requires significant computing power. To generate more, you'll need to subscribe for monthly credits. Your support also helps us keep building and improving ArtCraft!"
subtitle="
Creating high-quality videos requires significant computing power.
To generate more, you can subscribe to ArtCraft or buy ArtCraft credits.
You can also add 3rd party providers and use your existing services.
Your support helps us keep building and improving ArtCraft!
We're building the image and video tool that you can own forever.
"
/>
</div>
);
@@ -24,8 +24,12 @@ function getServiceProviderName(provider: GenerationProvider) : string {
return "Sora";
case GenerationProvider.Fal:
return "Fal";
case GenerationProvider.Grok:
return "Grok";
case GenerationProvider.Midjourney:
return "Midjourney";
case GenerationProvider.WorldLabs:
return "World Labs";
case GenerationProvider.Artcraft:
default:
return "Artcraft";
@@ -23,9 +23,11 @@ export function ProviderBillingModal({
let block;
switch (provider) {
case GenerationProvider.Fal:
case GenerationProvider.Grok:
case GenerationProvider.Midjourney:
case GenerationProvider.Sora:
case GenerationProvider.Fal:
case GenerationProvider.WorldLabs:
// NB: We're just going to ask users to set up billing on the provider's website.
block = <GenericProviderBillingBlock provider={provider} />;
break;
@@ -51,9 +51,19 @@ export const BillingSettingsPane = (args: BillingSettingsPaneProps) => {
return (
<>
<div className="space-y-4 text-base-fg">
<Label>Support ArtCraft</Label>
<p className="text-sm opacity-70">
You do not have to purchase anything from us to use ArtCraft, but
you can support ArtCraft development by subscribing or buying credits.
</p>
</div>
<br />
<div className="space-y-4 text-base-fg">
<div className="space-y-2">
<Label>Current Plan</Label>
<Label>Current ArtCraft Plan</Label>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2 text-xl font-semibold ">
<FontAwesomeIcon
@@ -102,7 +112,7 @@ export const BillingSettingsPane = (args: BillingSettingsPaneProps) => {
<div className="flex flex-col">
<Label htmlFor="credits" className="flex items-center gap-2">
Your credit balance
Your ArtCraft credit balance
</Label>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
@@ -1,8 +1,6 @@
import { SoundEffect } from "./SoundEffect";
export class SoundRegistry {
static #instance: SoundRegistry | undefined;
#sounds: Map<string, SoundEffect>;
private constructor() {
@@ -10,10 +8,30 @@ export class SoundRegistry {
}
public static getInstance() {
if (SoundRegistry.#instance === undefined) {
SoundRegistry.#instance = new SoundRegistry();
// NB(bt,2026-01-03): Our `nx` build setup is deeply flawed and in need
// of repair: Production builds will compile libraries to multiple
// independent symbolic spaces, making singleton pattern unreliable.
// Effectively, the singletons cannot be used across bundle boundaries.
// We're going to be gross and bind everything to the global namespace.
//
// To be clear, this does not work:
//
// class SoundRegistry {
// static #instance: SoundRegistry | undefined;
//
// [...]
//
// static getInstance() {
// if (SoundRegistry.#instance === undefined) {
// SoundRegistry.#instance = new SoundRegistry();
// }
// return SoundRegistry.#instance;
// }
if ((window as any).artcraft_sound_registry === undefined) {
(window as any).artcraft_sound_registry = new SoundRegistry();
}
return SoundRegistry.#instance;
return (window as any).artcraft_sound_registry;
}
public hasSound(key: string) : boolean {
+1 -1
View File
@@ -19,7 +19,7 @@ sqlite_db_file="/tmp/tasks.sqlite"
# it decoheres the and corrupts terminal output, and it's slow. This configuration
# allows us to start without it. Simply launch `nx` and the dev server as a separate
# process and leave tauri out of the loop
config_path="${rust_crate_path}/tauri.artcraft_3d.no_dev.conf.json"
config_path="${rust_crate_path}/tauri-dev-hot-reload.conf.json"
export TAURI_FRONTEND_PATH="${frontend_path}"
export TAURI_APP_PATH="${rust_crate_path}"
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
# This works on Linux and MacOS to launch the Rust dev server
set -euxo pipefail
echo "Running Artcraft Rust in Dev Mode..."
echo ""
echo "You'll need to launch the frontend dev server as a second script!"
echo ""
root_dir=$(pwd)
frontend_path="${root_dir}/frontend"
rust_crate_path="${root_dir}/crates/desktop/artcraft"
sqlite_db_file="/tmp/tasks.sqlite"
# The tauri dev server integration is super annoying: It eats ctrl-c interrupts,
# it decoheres the and corrupts terminal output, and it's slow. This configuration
# allows us to start without it. Simply launch `nx` and the dev server as a separate
# process and leave tauri out of the loop
config_path="${rust_crate_path}/tauri-dev-static.conf.json"
export TAURI_FRONTEND_PATH="${frontend_path}"
export TAURI_APP_PATH="${rust_crate_path}"
echo "Create database file..."
touch "${sqlite_db_file}"
sqlx_migrate() {
echo "SQLx migrate database file..."
sqlx migrate run \
--database-url "sqlite:${sqlite_db_file}" \
--source "${root_dir}/_sql/artcraft_migrations"
export DATABASE_URL="sqlite:${sqlite_db_file}"
}
sqlx_offline() {
echo "SQLx offline..."
export SQLX_OFFLINE=true
}
# NB: Switch this for actively developing queries.
#sqlx_migrate
sqlx_offline
# Issue with Linux performance
# https://github.com/tauri-apps/tauri/issues/13498
export WEBKIT_DISABLE_DMABUF_RENDERER=1
export WEBKIT_DISABLE_COMPOSITING_MODE=1
echo "Build and run..."
RUSTFLAGS="-Awarnings" cargo tauri dev \
--no-dev-server \
--no-dev-server-wait \
--no-watch \
--config "${config_path}"