feat: refresh welcome copy and Pro Max screenshot workflow

This commit is contained in:
Kaede Akino committed 2026-10-06 22:09:53 +08:00
1 parent e5bcfdb5c5
commit f297d0bd8d
8 files changed
+45 -42

No files matched your search

+17 -17
View File
@@ -6349,6 +6349,23 @@
}
}
},
"Command with ease, stay in control." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "随心发令,从容掌控。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隨心發令,從容掌控。"
}
}
}
},
"Commands" : {
"extractionState" : "manual",
"localizations" : {
@@ -34149,23 +34166,6 @@
}
}
},
"Your terminal, with judgment." : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "你的终端,自有判断。"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "你的終端,自有判斷。"
}
}
}
},
"[… %lld characters omitted …]" : {
"extractionState" : "manual",
"localizations" : {
@@ -250,8 +250,8 @@ extension AppStrings {
"Workspace Templates"
}
public static var yourTerminalWithJudgment: LocalizedStringResource {
"Your terminal, with judgment."
public static var commandWithEaseStayInControl: LocalizedStringResource {
"Command with ease, stay in control."
}
public static var cancelOperation: LocalizedStringResource {
+7 -7
View File
@@ -100,18 +100,18 @@ It checks both the simulator model identifier and the raw pixel dimensions:
| Selector | Capture device | Native capture size |
| --- | --- | --- |
| `iphone` | iPhone 17 Pro (6.3-inch), portrait | 1206×2622 |
| `iphone` | iPhone 17 Pro Max (6.9-inch), portrait | 1320×2868 |
| `ipad` | iPad Pro 13-inch (M5), landscape | 2752×2064 |
Create the exact simulators once if they are missing:
```sh
xcrun simctl create "iPhone 17 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-17-Pro com.apple.CoreSimulator.SimRuntime.iOS-27-0
xcrun simctl create "iPhone 17 Pro Max" com.apple.CoreSimulator.SimDeviceType.iPhone-17-Pro-Max com.apple.CoreSimulator.SimRuntime.iOS-27-0
xcrun simctl create "iPad Pro 13-inch (M5)" com.apple.CoreSimulator.SimDeviceType.iPad-Pro-13-inch-M5-12GB com.apple.CoreSimulator.SimRuntime.iOS-27-0
```
The lane does not resize iPhone captures or substitute a Pro Max. Existing
`com.akinokaede.termind/assets/app_store/*/iphone-6.5` artwork uses a separate 1284×2778 composition canvas;
The lane does not resize iPhone captures or substitute another device. Existing
`com.akinokaede.termind/assets/app_store/*/iphone-6.9` artwork uses a separate 1320×2868 composition canvas;
that folder describes the final artwork, not the screenshot device. Recapturing
does not regenerate those downstream assets automatically.
@@ -158,10 +158,10 @@ selected jobs without changing files. Defaults include only website-used scenes:
iPhone Assistant/SSH/Vault, iPad Metrics/SFTP/Vault, and Mac Workspace, in all three
locales. Use `scenes:` explicitly when another composition is needed.
The lane stages source copies and publishes
`<locale>/<device>/<feature>.png` only after every selected output succeeds. Old Pro Max captures
must be recaptured on iPhone 17 Pro before framing; they are rejected by size.
`<locale>/<device>/<feature>.png` only after every selected output succeeds. Old Pro captures
must be recaptured on iPhone 17 Pro Max before framing; they are rejected by size.
- iPhone uses frameit's iPhone 17 Pro Silver frame at native screenshot size.
- iPhone uses frameit's iPhone 17 Pro Max Silver frame at native screenshot size.
- iPad uses Apple's official iPad Pro (M5) 13-inch Space Black PNG as a custom
frameit device. Its opening matches the native capture exactly, with no resize.
Import the PNG once as described in the local frame templates section below, or pass
+14 -11
View File
@@ -49,18 +49,18 @@ class ScreenshotsTests < Minitest::Test
assert_equal ["zh-Hant"], capture.plan[:locales]
end
def test_a_renamed_pro_max_cannot_be_used_as_the_pro_capture_device
def test_a_renamed_pro_cannot_be_used_as_the_pro_max_capture_device
capture = runner(:ios, devices: "iphone")
capture.define_singleton_method(:command) do |*args|
JSON.generate("devices" => { "com.apple.CoreSimulator.SimRuntime.iOS-27-0" => [
{ "name" => "iPhone 17 Pro", "udid" => "wrong-model",
"deviceTypeIdentifier" => "com.apple.CoreSimulator.SimDeviceType.iPhone-17-Pro-Max" }
{ "name" => "iPhone 17 Pro Max", "udid" => "wrong-model",
"deviceTypeIdentifier" => "com.apple.CoreSimulator.SimDeviceType.iPhone-17-Pro" }
] })
end
assert_raises(RuntimeError) { capture.find_devices }
capture.define_singleton_method(:dimensions) { |_| [1320, 2868] }
capture.define_singleton_method(:dimensions) { |_| [1206, 2622] }
assert_raises(RuntimeError) do
capture.validate_dimensions("pro-max.png", Screenshots::DEVICES.fetch("iphone").fetch(:dimensions))
capture.validate_dimensions("pro.png", Screenshots::DEVICES.fetch("iphone").fetch(:dimensions))
end
end
@@ -191,7 +191,7 @@ class ScreenshotsTests < Minitest::Test
end
""
end
capture.define_singleton_method(:dimensions) { |_| [1206, 2622] }
capture.define_singleton_method(:dimensions) { |_| [1320, 2868] }
containers = [old_container, new_container]
status = Object.new
status.define_singleton_method(:success?) { true }
@@ -279,23 +279,26 @@ class ScreenshotFramesTests < Minitest::Test
def test_explicit_frame_paths_work_without_submodule_and_keep_source_bytes
FileUtils.remove_entry(File.join(@root, "com.akinokaede.termind"))
source = File.join(@root, "review-input/en/iphone/vault.png")
png(source, 1206, 2622)
png(source, 1320, 2868)
original_hash = Digest::SHA256.file(source).hexdigest
runner = ScreenshotFrames.new({ devices: "iphone", scenes: "vault", locales: "en",
input: "review-input", output: "review-output" }, root: @root)
downloader = Object.new
downloader.define_singleton_method(:frames_exist?) { true }
Frameit::FrameDownloader.stub(:new, downloader) do
runner.run { |options| png(File.join(options.fetch(:path), "iphone_framed.png"), 1350, 2760) }
runner.run do |options|
assert_equal "iPhone 17 Pro Max", options.fetch(:force_device_type)
png(File.join(options.fetch(:path), "iphone_framed.png"), 1458, 3006)
end
end
assert File.exist?(File.join(@root, "review-output/en/iphone/vault.png"))
assert_equal original_hash, Digest::SHA256.file(source).hexdigest
refute Dir.exist?(File.join(@root, "com.akinokaede.termind"))
end
def test_rejects_old_pro_max_sources_before_calling_frameit
def test_rejects_pro_sources_before_calling_frameit
source = File.join(@root, "com.akinokaede.termind/assets/captures/en/iphone/vault.png")
png(source, 1320, 2868)
png(source, 1206, 2622)
runner = ScreenshotFrames.new({ devices: "iphone", scenes: "vault", locales: "en" }, root: @root)
called = false
assert_raises(RuntimeError) { runner.run { called = true } }
@@ -305,7 +308,7 @@ class ScreenshotFramesTests < Minitest::Test
def test_missing_frameit_output_keeps_all_existing_outputs_and_sources
%w[en zh-hans].each do |locale|
png(File.join(@root, "com.akinokaede.termind/assets/captures/#{locale}/iphone/vault.png"), 1206, 2622)
png(File.join(@root, "com.akinokaede.termind/assets/captures/#{locale}/iphone/vault.png"), 1320, 2868)
end
destination = File.join(@root, "com.akinokaede.termind/assets/device_frames/en/iphone/vault.png")
FileUtils.mkdir_p(File.dirname(destination))
@@ -834,7 +834,7 @@ struct WelcomeView: View {
private var welcomeGreetings: [String] {
[
String(localized: AppStrings.Workspace.helloIMTermind),
String(localized: AppStrings.Workspace.yourTerminalWithJudgment),
String(localized: AppStrings.Workspace.commandWithEaseStayInControl),
String(localized: AppStrings.Workspace.sshAndSftpWithAnAssistantAtHand),
]
}
+1 -1
View File
@@ -80,7 +80,7 @@ class ScreenshotFrames
configuration = framefile.merge("default" => {})
force_device = case job[:device]
when "iphone"
"iPhone 17 Pro"
"iPhone 17 Pro Max"
when "ipad"
configuration["default"] = { "offset" => { "offset" => "+118+124", "width" => 2064 } }
"iPad Pro 13-inch (M5)"
+2 -2
View File
@@ -27,8 +27,8 @@ class Screenshots
}.freeze
MOBILE_SCENES = %w[vault sftp ssh metrics assistant].freeze
DEVICES = {
"iphone" => { name: "iPhone 17 Pro", type: "com.apple.CoreSimulator.SimDeviceType.iPhone-17-Pro",
dimensions: [1206, 2622] },
"iphone" => { name: "iPhone 17 Pro Max", type: "com.apple.CoreSimulator.SimDeviceType.iPhone-17-Pro-Max",
dimensions: [1320, 2868] },
"ipad" => { name: "iPad Pro 13-inch (M5)", type: "com.apple.CoreSimulator.SimDeviceType.iPad-Pro-13-inch-M5-12GB",
dimensions: [2752, 2064] }
}.freeze