Animate the Welcome prompt

This commit is contained in:
Kaede Akino committed 2026-08-28 22:19:30 +08:00
1 parent b4d52e08fb
commit ff42e2603d
6 files changed
+8270 -8210

No files matched your search

+17
View File
@@ -18,6 +18,7 @@
TRMD00000000000000100008 /* MarkdownView in Frameworks */ = {isa = PBXBuildFile; productRef = TRMD00000000000000100017 /* MarkdownView */; };
TRMD00000000000000100009 /* ListViewKit in Frameworks */ = {isa = PBXBuildFile; productRef = TRMD00000000000000100018 /* ListViewKit */; };
TRMD00000000000000100010 /* ScrubberKit in Frameworks */ = {isa = PBXBuildFile; productRef = TRMD00000000000000100019 /* ScrubberKit */; };
TRMD0000000000000010000B /* GlyphixTextFx in Frameworks */ = {isa = PBXBuildFile; productRef = TRMD0000000000000010001A /* GlyphixTextFx */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -93,6 +94,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
TRMD0000000000000010000B /* GlyphixTextFx in Frameworks */,
TRMD00000000000000100005 /* ZIPFoundation in Frameworks */,
TRMD00000000000000100008 /* MarkdownView in Frameworks */,
TRMD00000000000000100009 /* ListViewKit in Frameworks */,
@@ -166,6 +168,7 @@
name = Termind;
packageProductDependencies = (
TRMD00000000000000100011 /* CSSH2 */,
TRMD0000000000000010001A /* GlyphixTextFx */,
TRMD00000000000000100016 /* GhosttyKit */,
TRMD00000000000000100012 /* GhosttyTerminal */,
TRMD00000000000000100013 /* GhosttyTheme */,
@@ -266,6 +269,7 @@
minimizedProjectReferenceProxies = 1;
packageReferences = (
TRMD00000000000000100021 /* XCRemoteSwiftPackageReference "libssh2-spm" */,
TRMD00000000000000100028 /* XCRemoteSwiftPackageReference "GlyphixTextFx" */,
TRMD00000000000000100022 /* XCRemoteSwiftPackageReference "libghostty-spm" */,
TRMD00000000000000100023 /* XCRemoteSwiftPackageReference "openssl-spm" */,
TRMD00000000000000100024 /* XCRemoteSwiftPackageReference "ZIPFoundation" */,
@@ -642,6 +646,14 @@
revision = 4c0e55c2a257ceecae8f86c4781cfd99a6572347;
};
};
TRMD00000000000000100028 /* XCRemoteSwiftPackageReference "GlyphixTextFx" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Lakr233/GlyphixTextFx.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@@ -690,6 +702,11 @@
package = TRMD00000000000000100027 /* XCRemoteSwiftPackageReference "ScrubberKit" */;
productName = ScrubberKit;
};
TRMD0000000000000010001A /* GlyphixTextFx */ = {
isa = XCSwiftPackageProductDependency;
package = TRMD00000000000000100028 /* XCRemoteSwiftPackageReference "GlyphixTextFx" */;
productName = GlyphixTextFx;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = TRMD00000000000000000090 /* Project object */;
@@ -1,6 +1,24 @@
{
"originHash" : "61efd12edd2ce744dc62d8629946b85f4c36fb609927b7fdde9d65754310b671",
"originHash" : "f4c3143502b0cd833f99b8362111eda2d3f30ca9087b720290ed37e2efe4f2c9",
"pins" : [
{
"identity" : "choreographer",
"kind" : "remoteSourceControl",
"location" : "https://github.com/unixzii/Choreographer",
"state" : {
"revision" : "04dc84bfe380b8c5910ed7d0607765fddedd0460",
"version" : "0.2.0"
}
},
{
"identity" : "glyphixtextfx",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Lakr233/GlyphixTextFx.git",
"state" : {
"revision" : "e1d0aa71c1849363a1bbef061d3d92f10481e62c",
"version" : "2.3.6"
}
},
{
"identity" : "highlightr",
"kind" : "remoteSourceControl",
@@ -82,6 +100,15 @@
"version" : "3.6.2"
}
},
{
"identity" : "respring",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ktiays/Respring",
"state" : {
"revision" : "2148e8fce312b4dcf76b8f909226b19f3ae38186",
"version" : "1.1.0"
}
},
{
"identity" : "scrubberkit",
"kind" : "remoteSourceControl",
@@ -126,6 +153,15 @@
"version" : "2.13.9"
}
},
{
"identity" : "with",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ktiays/With",
"state" : {
"revision" : "98edf55b91436b2c13a76fc2b66dc3b34627d8d4",
"version" : "2.1.5"
}
},
{
"identity" : "zipfoundation",
"kind" : "remoteSourceControl",
@@ -1,3 +1,4 @@
import GlyphixTextFx
import SwiftUI
import UniformTypeIdentifiers
@@ -756,10 +757,27 @@ private struct PaneView: View {
struct WelcomeView: View {
@Environment(AppModel.self) private var app
@Environment(WindowModel.self) private var window
@Environment(\.accessibilityReduceMotion) private var accessibilityReduceMotion
@State private var query = ""
@State private var welcomeMessage = " "
@FocusState private var isSearchFocused: Bool
private var welcomeGreetings: [String] {
[
String(localized: "Hello, I'm Termind."),
String(localized: "Your terminal, with judgment."),
String(localized: "SSH and SFTP, with an assistant at hand."),
]
}
private var welcomePrompts: [String] {
[
String(localized: "What would you like to do?"),
String(localized: "What do you feel like doing?"),
]
}
var body: some View {
ScrollView {
VStack(spacing: Metrics.Space.xxl) {
@@ -779,20 +797,28 @@ struct WelcomeView: View {
}
private var header: some View {
VStack(spacing: Metrics.Space.s) {
Image("TermindGlyph")
.resizable()
.renderingMode(.template)
.scaledToFit()
.frame(width: 88, height: 88)
.foregroundStyle(.tertiary)
.accessibilityHidden(true)
Text("Termind")
.font(.largeTitle.weight(.semibold))
Text("SSH and SFTP, with an assistant at hand.")
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
}
GlyphixText(welcomeMessage)
.glyphixTextFont(.systemFont(ofSize: 30, weight: .semibold))
.glyphixTextColor(.labelColor)
.glyphixTextAnimationDisabled(accessibilityReduceMotion)
.multilineTextAlignment(.center)
.frame(maxWidth: .infinity, minHeight: 88, maxHeight: 88)
.accessibilityElement(children: .ignore)
.accessibilityLabel(Text(verbatim: welcomeMessage))
.task {
let greeting = welcomeGreetings.randomElement() ?? welcomeGreetings[0]
let prompt = welcomePrompts.randomElement() ?? welcomePrompts[0]
if !accessibilityReduceMotion {
try? await Task.sleep(for: .milliseconds(120))
}
guard !Task.isCancelled else { return }
welcomeMessage = greeting
try? await Task.sleep(for: .seconds(2))
guard !Task.isCancelled else { return }
welcomeMessage = prompt
}
}
// MARK: - Search
@@ -1,16 +0,0 @@
{
"images" : [
{
"filename" : "TermindGlyph.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<!-- Monochrome trace of the foreground mark in the GPT reference image. -->
<rect
x="12"
y="12"
width="232"
height="232"
rx="50"
fill="none"
stroke="#000000"
stroke-width="8"
/>
<g fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round">
<!-- The channels sit behind the prompt and meet beneath its point. -->
<path d="M105 119C139 119 146 78 163 72C173 68 181 69 190 67" stroke-width="9"/>
<path d="M105 119C139 119 151 98 174 97C187 96 195 97 204 97" stroke-width="9"/>
<path d="M105 119C137 119 150 121 170 126C181 129 189 133 197 134" stroke-width="9"/>
<path d="M105 119C136 119 147 144 164 153C173 158 181 160 190 160" stroke-width="9"/>
<!-- Heavy terminal chevron, matching the rounded proportions of the source. -->
<path d="M68 76L108 119 68 158" stroke-width="29"/>
</g>
<g fill="#000000">
<circle cx="194" cy="66" r="9"/>
<circle cx="208" cy="97" r="9"/>
<circle cx="201" cy="135" r="9"/>
<circle cx="194" cy="161" r="9"/>
<rect x="96" y="165" width="65" height="19" rx="9.5"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because it is too large. Load diff