Compare commits

...

6 Commits

Author SHA1 Message Date
Jon Staab b14c3ab345 Bump version 2025-05-14 13:52:37 -07:00
Jon Staab 823058e335 Add setting for font size 2025-05-13 14:31:34 -07:00
Jon Staab 60ec6924f3 Fix thunks status layout 2025-05-13 10:35:42 -07:00
Jon Staab 18fc895fcb Tweak navigation to improve white labeled instances 2025-05-13 10:14:20 -07:00
Jon Staab 42295159a0 Update remove-pnpm-overrides to use package version of welshman (hack) 2025-05-13 09:06:53 -07:00
Jon Staab db408ac30d Stop propagation on thunk status 2025-05-12 15:35:13 -07:00
18 changed files with 120 additions and 61 deletions
+7
View File
@@ -1,5 +1,12 @@
# Changelog # Changelog
# 1.0.4
* Fix thunk status click handler
* Remove duplicate dependencies
* Improve navigation on white-labeled instances
* Add setting for font size
# 1.0.3 # 1.0.3
* Add light theme * Add light theme
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "social.flotilla" applicationId "social.flotilla"
minSdk rootProject.ext.minSdkVersion minSdk rootProject.ext.minSdkVersion
targetSdk rootProject.ext.targetSdkVersion targetSdk rootProject.ext.targetSdkVersion
versionCode 17 versionCode 18
versionName "1.0.3" versionName "1.0.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions { aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
+4 -4
View File
@@ -351,14 +351,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 10; CURRENT_PROJECT_VERSION = 11;
DEVELOPMENT_TEAM = S26U9DYW3A; DEVELOPMENT_TEAM = S26U9DYW3A;
INFOPLIST_FILE = App/Info.plist; INFOPLIST_FILE = App/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Flotilla Chat"; INFOPLIST_KEY_CFBundleDisplayName = "Flotilla Chat";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 1.0.3; MARKETING_VERSION = 1.0.4;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = social.flotilla; PRODUCT_BUNDLE_IDENTIFIER = social.flotilla;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -376,14 +376,14 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 10; CURRENT_PROJECT_VERSION = 11;
DEVELOPMENT_TEAM = S26U9DYW3A; DEVELOPMENT_TEAM = S26U9DYW3A;
INFOPLIST_FILE = App/Info.plist; INFOPLIST_FILE = App/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Flotilla Chat"; INFOPLIST_KEY_CFBundleDisplayName = "Flotilla Chat";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MARKETING_VERSION = 1.0.3; MARKETING_VERSION = 1.0.4;
PRODUCT_BUNDLE_IDENTIFIER = social.flotilla; PRODUCT_BUNDLE_IDENTIFIER = social.flotilla;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "flotilla", "name": "flotilla",
"version": "1.0.3", "version": "1.0.4",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite dev", "dev": "vite dev",
+6 -1
View File
@@ -12,7 +12,12 @@ if (!pkgName?.endsWith("package.json")) {
const pkg = JSON.parse(fs.readFileSync(pkgName, "utf8")) const pkg = JSON.parse(fs.readFileSync(pkgName, "utf8"))
if (pkg.pnpm && pkg.pnpm.overrides) { if (pkg.pnpm && pkg.pnpm.overrides) {
delete pkg.pnpm.overrides // Use $package notation to make sure we only get one copy of each welshman dependency
// TODO: move welshman to a single package to straighten all this out.
for (const k of Object.keys(pkg.pnpm.overrides)) {
pkg.pnpm.overrides[k] = '$' + k
}
fs.writeFileSync(pkgName, JSON.stringify(pkg, null, 2) + "\n") fs.writeFileSync(pkgName, JSON.stringify(pkg, null, 2) + "\n")
console.log("Removed pnpm.overrides from package.json") console.log("Removed pnpm.overrides from package.json")
} else { } else {
+4
View File
@@ -388,6 +388,10 @@ progress[value]::-webkit-progress-value {
@apply w-full md:left-[18.5rem] md:w-[calc(100%-18.5rem-var(--sair))]; @apply w-full md:left-[18.5rem] md:w-[calc(100%-18.5rem-var(--sair))];
} }
.cw-full {
@apply w-full md:left-[4rem] md:w-[calc(100%-4rem-var(--sair))];
}
.cb { .cb {
@apply md:bottom-sai bottom-[calc(var(--saib)+3.5rem)]; @apply md:bottom-sai bottom-[calc(var(--saib)+3.5rem)];
} }
+15 -20
View File
@@ -5,35 +5,30 @@
import CardButton from "@lib/components/CardButton.svelte" import CardButton from "@lib/components/CardButton.svelte"
import MenuSpacesItem from "@app/components/MenuSpacesItem.svelte" import MenuSpacesItem from "@app/components/MenuSpacesItem.svelte"
import SpaceAdd from "@app/components/SpaceAdd.svelte" import SpaceAdd from "@app/components/SpaceAdd.svelte"
import {userRoomsByUrl, PLATFORM_RELAY} from "@app/state" import {userRoomsByUrl} from "@app/state"
import {pushModal} from "@app/modal" import {pushModal} from "@app/modal"
const addSpace = () => pushModal(SpaceAdd) const addSpace = () => pushModal(SpaceAdd)
</script> </script>
<div class="column menu gap-2"> <div class="column menu gap-2">
{#if PLATFORM_RELAY} {#if $userRoomsByUrl.size > 0}
<MenuSpacesItem url={PLATFORM_RELAY} />
<Divider />
{:else if $userRoomsByUrl.size > 0}
{#each $userRoomsByUrl.keys() as url (url)} {#each $userRoomsByUrl.keys() as url (url)}
<MenuSpacesItem {url} /> <MenuSpacesItem {url} />
{/each} {/each}
<Divider /> <Divider />
{/if} {/if}
{#if !PLATFORM_RELAY} <Button onclick={addSpace}>
<Button onclick={addSpace}> <CardButton>
<CardButton> {#snippet icon()}
{#snippet icon()} <div><Icon icon="login-2" size={7} /></div>
<div><Icon icon="login-2" size={7} /></div> {/snippet}
{/snippet} {#snippet title()}
{#snippet title()} <div>Add a space</div>
<div>Add a space</div> {/snippet}
{/snippet} {#snippet info()}
{#snippet info()} <div>Join or create a new space</div>
<div>Join or create a new space</div> {/snippet}
{/snippet} </CardButton>
</CardButton> </Button>
</Button>
{/if}
</div> </div>
+7 -7
View File
@@ -10,7 +10,7 @@
import Link from "@lib/components/Link.svelte" import Link from "@lib/components/Link.svelte"
import Profile from "@app/components/Profile.svelte" import Profile from "@app/components/Profile.svelte"
import ProfileInfo from "@app/components/ProfileInfo.svelte" import ProfileInfo from "@app/components/ProfileInfo.svelte"
import {makeChatPath} from "@app/routes" import {pubkeyLink} from "@app/state"
type Props = { type Props = {
pubkey: string pubkey: string
@@ -37,9 +37,9 @@
<div class="card2 bg-alt col-2 shadow-xl"> <div class="card2 bg-alt col-2 shadow-xl">
<div class="flex justify-between"> <div class="flex justify-between">
<Profile {pubkey} {url} /> <Profile {pubkey} {url} />
<Link class="btn btn-primary hidden sm:flex" href={makeChatPath([pubkey])}> <Link external href={pubkeyLink(pubkey)} class="btn btn-primary hidden sm:flex">
<Icon icon="letter" /> <Icon icon="user-circle" />
Start a Chat See Complete Profile
</Link> </Link>
</div> </div>
<ProfileInfo {pubkey} {url} /> <ProfileInfo {pubkey} {url} />
@@ -48,8 +48,8 @@
Last active {formatTimestampRelative($events[0].created_at)} Last active {formatTimestampRelative($events[0].created_at)}
</div> </div>
{/if} {/if}
<Link class="btn btn-primary sm:hidden" href={makeChatPath([pubkey])}> <Link external href={pubkeyLink(pubkey)} class="btn btn-primary sm:hidden">
<Icon icon="letter" /> <Icon icon="user-circle" />
Start a Chat See Complete Profile
</Link> </Link>
</div> </div>
+12 -5
View File
@@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import type {Snippet} from "svelte"
import {page} from "$app/stores" import {page} from "$app/stores"
import {goto} from "$app/navigation" import {goto} from "$app/navigation"
import {splitAt} from "@welshman/lib" import {splitAt} from "@welshman/lib"
@@ -16,8 +17,9 @@
import {pushModal} from "@app/modal" import {pushModal} from "@app/modal"
import {makeSpacePath} from "@app/routes" import {makeSpacePath} from "@app/routes"
import {notifications} from "@app/notifications" import {notifications} from "@app/notifications"
interface Props {
children?: import("svelte").Snippet type Props = {
children?: Snippet
} }
const {children}: Props = $props() const {children}: Props = $props()
@@ -118,9 +120,14 @@
notification={$notifications.has("/chat")}> notification={$notifications.has("/chat")}>
<Avatar icon="letter" class="!h-10 !w-10" /> <Avatar icon="letter" class="!h-10 !w-10" />
</PrimaryNavItem> </PrimaryNavItem>
<PrimaryNavItem title="Spaces" onclick={showSpacesMenu} notification={anySpaceNotifications}> {#if !PLATFORM_RELAY}
<Avatar icon="settings-minimalistic" class="!h-10 !w-10" /> <PrimaryNavItem
</PrimaryNavItem> title="Spaces"
onclick={showSpacesMenu}
notification={anySpaceNotifications}>
<Avatar icon="settings-minimalistic" class="!h-10 !w-10" />
</PrimaryNavItem>
{/if}
</div> </div>
<PrimaryNavItem title="Settings" onclick={showSettingsMenu}> <PrimaryNavItem title="Settings" onclick={showSettingsMenu}>
<Avatar icon="settings" src={$userProfile?.picture} class="!h-10 !w-10" /> <Avatar icon="settings" src={$userProfile?.picture} class="!h-10 !w-10" />
+1 -1
View File
@@ -105,7 +105,7 @@
{#if url && $reports.length > 0} {#if url && $reports.length > 0}
<button <button
type="button" type="button"
data-tip="{`This content has been reported as "${displayList(reportReasons)}".`}}" data-tip={`This content has been reported as "${displayList(reportReasons)}".`}
class="btn btn-error btn-xs tooltip-right flex items-center gap-1 rounded-full" class="btn btn-error btn-xs tooltip-right flex items-center gap-1 rounded-full"
class:tooltip={!noTooltip && !isMobile} class:tooltip={!noTooltip && !isMobile}
onclick={stopPropagation(preventDefault(onReportClick))}> onclick={stopPropagation(preventDefault(onReportClick))}>
+10 -7
View File
@@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import {nth} from "@welshman/lib" import {stopPropagation} from "svelte/legacy"
import {nth, noop} from "@welshman/lib"
import {PublishStatus} from "@welshman/net" import {PublishStatus} from "@welshman/net"
import { import {
MergedThunk, MergedThunk,
@@ -60,9 +61,11 @@
{@const url = failedUrls[0]} {@const url = failedUrls[0]}
{@const status = $thunk.status[url]} {@const status = $thunk.status[url]}
{@const message = $thunk.details[url]} {@const message = $thunk.details[url]}
<div class="flex justify-end px-1 text-xs {restProps.class}"> <button
class="flex w-full justify-end px-1 text-xs {restProps.class}"
onclick={stopPropagation(noop)}>
<Tippy <Tippy
class="flex items-center {restProps.class}" class="flex items-center"
component={ThunkStatusDetail} component={ThunkStatusDetail}
props={{url, message, status, retry}} props={{url, message, status, retry}}
params={{interactive: true}}> params={{interactive: true}}>
@@ -73,10 +76,10 @@
</span> </span>
{/snippet} {/snippet}
</Tippy> </Tippy>
</div> </button>
{:else if showPending} {:else if showPending}
<div class="flex justify-end px-1 text-xs {restProps.class}"> <div class="flex w-full justify-end px-1 text-xs {restProps.class}">
<span class="flex items-center gap-1 {restProps.class}"> <span class="flex items-center gap-1">
<span class="loading loading-spinner mx-1 h-3 w-3 translate-y-px"></span> <span class="loading loading-spinner mx-1 h-3 w-3 translate-y-px"></span>
<span class="opacity-50">Sending...</span> <span class="opacity-50">Sending...</span>
<button <button
@@ -84,7 +87,7 @@
class="underline transition-all" class="underline transition-all"
class:link={canCancel} class:link={canCancel}
class:opacity-25={!canCancel} class:opacity-25={!canCancel}
onclick={abort}> onclick={stopPropagation(abort)}>
Cancel Cancel
</button> </button>
</span> </span>
+2
View File
@@ -296,6 +296,7 @@ export type Settings = {
report_usage: boolean report_usage: boolean
report_errors: boolean report_errors: boolean
send_delay: number send_delay: number
font_size: number
} }
} }
@@ -305,6 +306,7 @@ export const defaultSettings = {
report_usage: true, report_usage: true,
report_errors: true, report_errors: true,
send_delay: 3000, send_delay: 3000,
font_size: 1,
} }
export const settings = deriveEventsMapped<Settings>(repository, { export const settings = deriveEventsMapped<Settings>(repository, {
+2 -4
View File
@@ -14,9 +14,7 @@
{@render props.input?.()} {@render props.input?.()}
</div> </div>
</div> </div>
<div class="scroll-container overflow-auto"> <div class="scroll-container content-sizing overflow-auto pt-2">
<div class="content-sizing"> {@render props.content?.()}
{@render props.content?.()}
</div>
</div> </div>
</div> </div>
+14 -6
View File
@@ -3,20 +3,28 @@
interface Props { interface Props {
label?: Snippet label?: Snippet
secondary?: Snippet
input?: Snippet input?: Snippet
info?: Snippet info?: Snippet
[key: string]: any [key: string]: any
} }
const {label, input, info, ...props}: Props = $props() const {label, secondary, input, info, ...props}: Props = $props()
</script> </script>
<div class="flex flex-col gap-2 {props.class}"> <div class="flex flex-col gap-2 {props.class}">
{#if label} <div class="flex items-center justify-between">
<label class="flex items-center gap-2 font-bold"> {#if label}
{@render label()} <label class="flex items-center gap-2 font-bold">
</label> {@render label()}
{/if} </label>
{/if}
{#if secondary}
<label class="flex items-center gap-2">
{@render secondary()}
</label>
{/if}
</div>
{@render input?.()} {@render input?.()}
{#if info} {#if info}
<p class="text-sm"> <p class="text-sm">
+13 -1
View File
@@ -51,7 +51,13 @@
import {setupTracking} from "@app/tracking" import {setupTracking} from "@app/tracking"
import {setupAnalytics} from "@app/analytics" import {setupAnalytics} from "@app/analytics"
import {nsecDecode} from "@lib/util" import {nsecDecode} from "@lib/util"
import {INDEXER_RELAYS, userMembership, ensureUnwrapped, canDecrypt} from "@app/state" import {
INDEXER_RELAYS,
userMembership,
userSettingValues,
ensureUnwrapped,
canDecrypt,
} from "@app/state"
import {loadUserData, listenForNotifications} from "@app/requests" import {loadUserData, listenForNotifications} from "@app/requests"
import {theme} from "@app/theme" import {theme} from "@app/theme"
import * as commands from "@app/commands" import * as commands from "@app/commands"
@@ -126,6 +132,12 @@
document.body.setAttribute("data-theme", $theme) document.body.setAttribute("data-theme", $theme)
}) })
// Sync font size
userSettingValues.subscribe($userSettingValues => {
// @ts-ignore
document.documentElement.style["font-size"] = `${$userSettingValues.font_size}rem`
})
if (!db) { if (!db) {
setupTracking() setupTracking()
setupAnalytics() setupAnalytics()
+1 -1
View File
@@ -52,7 +52,7 @@
{/snippet} {/snippet}
</CardButton> </CardButton>
</Link> </Link>
<Link href="/people"> <Link href="/chat">
<CardButton> <CardButton>
{#snippet icon()} {#snippet icon()}
<div><Icon icon="chat-round" size={7} /></div> <div><Icon icon="chat-round" size={7} /></div>
+1 -1
View File
@@ -28,7 +28,7 @@
}) })
</script> </script>
<Page> <Page class="cw-full">
<ContentSearch> <ContentSearch>
{#snippet input()} {#snippet input()}
<label class="row-2 input input-bordered"> <label class="row-2 input input-bordered">
+18
View File
@@ -166,6 +166,24 @@
<p>Choose a media server type and url for files you upload to {PLATFORM_NAME}.</p> <p>Choose a media server type and url for files you upload to {PLATFORM_NAME}.</p>
{/snippet} {/snippet}
</Field> </Field>
<strong class="text-lg">Accessibility</strong>
<Field>
{#snippet label()}
<p>Font size</p>
{/snippet}
{#snippet secondary()}
<p>{Math.round(settings.font_size * 100)}%</p>
{/snippet}
{#snippet input()}
<input
class="range range-primary"
type="range"
min="0.8"
max="1.3"
step="0.05"
bind:value={settings.font_size} />
{/snippet}
</Field>
<div class="mt-4 flex flex-row items-center justify-between gap-4"> <div class="mt-4 flex flex-row items-center justify-between gap-4">
<Button class="btn btn-neutral" onclick={reset}>Discard Changes</Button> <Button class="btn btn-neutral" onclick={reset}>Discard Changes</Button>
<Button type="submit" class="btn btn-primary">Save Changes</Button> <Button type="submit" class="btn btn-primary">Save Changes</Button>