Files
Felitendo ff0d3108fe feat: merge the web dashboard into the monorepo as ftstore admin
FTStore now holds both halves of the product:

  ios/   the swift app — the fork of claration/Feather, unchanged apart
         from its new home
  web/   FTStore Admin, formerly its own repository. serves the
         dashboard at /admin, the ftstore.json feed and IPA downloads

app-repo.json and Images/ stay at the repo root on purpose: the former is
a published AltStore source whose raw.githubusercontent URL is what
installed copies resolve updates through, so moving it would break every
subscriber.

The admin server is renamed throughout: package ftstore-admin, images
ghcr.io/<owner>/ftstore-admin-{app,worker}, postgres role/db ftstore,
session cookie ftstore_session, temp dir /tmp/ftstore, backup type
ftstore-settings, outbound user-agent FTStoreAdmin. backups written under the old
name still import, and compose is pinned to name: ftstore so the
volume prefix does not follow the directory name.

apply-rebrand.sh gains a relocation step: upstream's tree is rooted at
the repo root while ours lives in ios/, so a merge drops Feather's files
next to ios/ and the script folds them in before renaming. it never
touches web/. still idempotent.

release tags are namespaced — v* for the app, web-v* for the server —
so a server release no longer triggers a macOS build or rewrites
app-repo.json. workflows are prefixed ios-/web- and path-filtered.
2026-08-03 10:25:03 +02:00

97 lines
2.3 KiB
Swift

//
// SectionProminentHeaderWrapper.swift
// Feather
//
// Created by samara on 11.04.2025.
//
import SwiftUI
public struct NBSection<Content, Footer>: View
where Content: View,
Footer: View
{
private var _headerText: String
private var _headerTextSecondary: String?
private var _systemName: String?
private var _content: Content
private var _footer: Footer
public init(_ headerText: String,
secondary headerTextSecondary: String? = nil,
systemName: String? = nil,
@ViewBuilder content: () -> Content,
@ViewBuilder footer: () -> Footer
) {
self._headerText = headerText
self._headerTextSecondary = headerTextSecondary
self._systemName = systemName
self._content = content()
self._footer = footer()
}
public init(_ headerText: String,
secondary headerTextSecondary: String? = nil,
systemName: String? = nil,
@ViewBuilder content: () -> Content
) where Footer == EmptyView {
self._headerText = headerText
self._headerTextSecondary = headerTextSecondary
self._systemName = systemName
self._content = content()
self._footer = EmptyView()
}
public var body: some View {
Section(
header:
HStack(alignment: .center, spacing: 4) {
if let _systemName {
Image(systemName: _systemName)
.font(.system(size: 12))
.offset(y: -2)
}
Text(_headerText)
.fontWeight(.bold)
.font(.title2)
.foregroundStyle(.primary)
Spacer()
if let _headerTextSecondary {
if #available(iOS 26.0, *) {
Text(_headerTextSecondary)
.font(.caption)
.foregroundStyle(.secondary)
.contentTransition(.numericText())
.padding(.horizontal, 8)
.padding(.vertical, 4.4)
.background(Color(uiColor: .quaternarySystemFill))
.clipShape(Capsule())
.glassEffect()
} else {
Text(_headerTextSecondary)
.font(.caption)
.foregroundStyle(.secondary)
.contentTransition(.numericText())
.padding(.horizontal, 8)
.padding(.vertical, 4.4)
.background(Color(uiColor: .quaternarySystemFill))
.clipShape(Capsule())
}
}
}
.offset(y: 2)
,
footer: _footer
.font(.caption)
.foregroundColor(.secondary)
) {
_content
}
.headerProminence(.increased)
}
}