fix: capitalize Terebi application name
This commit is contained in:
@@ -47,11 +47,11 @@ release:
|
|||||||
install: release
|
install: release
|
||||||
mkdir -p "$(APPDIR)" "$(PREFIX)/bin"
|
mkdir -p "$(APPDIR)" "$(PREFIX)/bin"
|
||||||
rm -f "$(PREFIX)/lib/terebi/terebi"
|
rm -f "$(PREFIX)/lib/terebi/terebi"
|
||||||
rm -rf "$(PREFIX)/lib/terebi/terebi.app" "$(APPDIR)/terebi.app"
|
rm -rf "$(PREFIX)/lib/terebi/terebi.app" "$(APPDIR)/terebi.app" "$(APPDIR)/Terebi.app"
|
||||||
cp -R ".build/release/terebi.app" "$(APPDIR)/terebi.app"
|
cp -R ".build/release/terebi.app" "$(APPDIR)/Terebi.app"
|
||||||
ln -sfn "$$(cd "$(APPDIR)" && pwd)/terebi.app/Contents/MacOS/terebi-cli" "$(PREFIX)/bin/terebi"
|
ln -sfn "$$(cd "$(APPDIR)" && pwd)/Terebi.app/Contents/MacOS/terebi-cli" "$(PREFIX)/bin/terebi"
|
||||||
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "$(APPDIR)/terebi.app"
|
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "$(APPDIR)/Terebi.app"
|
||||||
mdimport "$(APPDIR)/terebi.app"
|
mdimport "$(APPDIR)/Terebi.app"
|
||||||
|
|
||||||
$(BUILD_DIR):
|
$(BUILD_DIR):
|
||||||
mkdir -p "$@"
|
mkdir -p "$@"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export PATH="$HOME/.local/bin:$PATH"
|
|||||||
terebi --help
|
terebi --help
|
||||||
```
|
```
|
||||||
|
|
||||||
Installation builds a release, places `terebi.app` in `~/Applications`, registers it with Launch Services, and requests Spotlight indexing. The CLI symlink is `~/.local/bin/terebi`; any old app under `~/.local/lib/terebi` is removed. Quit running players before updating.
|
Installation builds a release, places `Terebi.app` in `~/Applications`, registers it with Launch Services, and requests Spotlight indexing. The application display name is **Terebi**; the CLI remains `~/.local/bin/terebi`. Any old app under `~/.local/lib/terebi` or lowercase installed bundle is removed. Quit running players before updating.
|
||||||
|
|
||||||
Use `make install APPDIR="/Applications"` to change the app directory (it must be writable), `PREFIX="/custom/path"` to change the CLI prefix (`bin/terebi`), or both. Use `make release` for just `.build/release/terebi.app`.
|
Use `make install APPDIR="/Applications"` to change the app directory (it must be writable), `PREFIX="/custom/path"` to change the CLI prefix (`bin/terebi`), or both. Use `make release` for just `.build/release/terebi.app`.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleExecutable</key><string>terebi</string>
|
<key>CFBundleExecutable</key><string>terebi</string>
|
||||||
<key>CFBundleIdentifier</key><string>local.personal.terebi</string>
|
<key>CFBundleIdentifier</key><string>local.personal.terebi</string>
|
||||||
<key>CFBundleName</key><string>terebi</string>
|
<key>CFBundleName</key><string>Terebi</string>
|
||||||
|
<key>CFBundleDisplayName</key><string>Terebi</string>
|
||||||
<key>CFBundlePackageType</key><string>APPL</string>
|
<key>CFBundlePackageType</key><string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key><string>0.1</string>
|
<key>CFBundleShortVersionString</key><string>0.1</string>
|
||||||
<key>LSMinimumSystemVersion</key><string>15.0</string>
|
<key>LSMinimumSystemVersion</key><string>15.0</string>
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ enum TerebiBootstrap {
|
|||||||
let payload = app.appendingPathComponent("Contents/Frameworks/libterebi-player.dylib")
|
let payload = app.appendingPathComponent("Contents/Frameworks/libterebi-player.dylib")
|
||||||
guard let library = dlopen(payload.path, RTLD_NOW | RTLD_LOCAL) else {
|
guard let library = dlopen(payload.path, RTLD_NOW | RTLD_LOCAL) else {
|
||||||
let detail = dlerror().map { String(cString: $0) } ?? "The dynamic loader could not load the player."
|
let detail = dlerror().map { String(cString: $0) } ?? "The dynamic loader could not load the player."
|
||||||
fail("Could not load the player: \(detail)\n\nPlayer library: \(payload.path)\nRebuild and reinstall terebi.")
|
fail("Could not load the player: \(detail)\n\nPlayer library: \(payload.path)\nRebuild and reinstall Terebi.")
|
||||||
}
|
}
|
||||||
guard let entry = dlsym(library, "terebi_app_main") else {
|
guard let entry = dlsym(library, "terebi_app_main") else {
|
||||||
fail("The player library is missing its application entry point. Rebuild and reinstall terebi.")
|
fail("The player library is missing its application entry point. Rebuild and reinstall Terebi.")
|
||||||
}
|
}
|
||||||
// Keep the declared app executable alive so LaunchServices retains its identity.
|
// Keep the declared app executable alive so LaunchServices retains its identity.
|
||||||
typealias PlayerMain = @convention(c) () -> Void
|
typealias PlayerMain = @convention(c) () -> Void
|
||||||
@@ -29,7 +29,7 @@ enum TerebiBootstrap {
|
|||||||
application.activate(ignoringOtherApps: true)
|
application.activate(ignoringOtherApps: true)
|
||||||
let alert = NSAlert()
|
let alert = NSAlert()
|
||||||
alert.alertStyle = .critical
|
alert.alertStyle = .critical
|
||||||
alert.messageText = "terebi could not start"
|
alert.messageText = "Terebi could not start"
|
||||||
alert.informativeText = message
|
alert.informativeText = message
|
||||||
alert.addButton(withTitle: "Quit")
|
alert.addButton(withTitle: "Quit")
|
||||||
alert.runModal()
|
alert.runModal()
|
||||||
|
|||||||
+11
-11
@@ -220,7 +220,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
guard canCast, let source = currentMedia, let handle else { return }
|
guard canCast, let source = currentMedia, let handle else { return }
|
||||||
cancelYouTubeResolution()
|
cancelYouTubeResolution()
|
||||||
commandError = nil
|
commandError = nil
|
||||||
casting.start(to: device, source: source, title: fileName ?? "terebi", subtitle: selectedSubtitle,
|
casting.start(to: device, source: source, title: fileName ?? "Terebi", subtitle: selectedSubtitle,
|
||||||
handle: handle, snapshot: state, playing: playing ?? effectivePlaying,
|
handle: handle, snapshot: state, playing: playing ?? effectivePlaying,
|
||||||
volume: volume, audibleVolume: lastAudibleVolume)
|
volume: volume, audibleVolume: lastAudibleVolume)
|
||||||
revealControls()
|
revealControls()
|
||||||
@@ -555,7 +555,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
isSeeking = false
|
isSeeking = false
|
||||||
seekPosition = 0
|
seekPosition = 0
|
||||||
window?.representedURL = source.url
|
window?.representedURL = source.url
|
||||||
window?.title = fileName ?? "terebi"
|
window?.title = fileName ?? "Terebi"
|
||||||
revealControls()
|
revealControls()
|
||||||
systemPlayback?.update()
|
systemPlayback?.update()
|
||||||
}
|
}
|
||||||
@@ -711,7 +711,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
commandError = nil
|
commandError = nil
|
||||||
isSeeking = false
|
isSeeking = false
|
||||||
window?.representedURL = nil
|
window?.representedURL = nil
|
||||||
window?.title = "terebi"
|
window?.title = "Terebi"
|
||||||
revealControls()
|
revealControls()
|
||||||
systemPlayback?.update()
|
systemPlayback?.update()
|
||||||
}
|
}
|
||||||
@@ -762,7 +762,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
func attachWindow(_ window: NSWindow) {
|
func attachWindow(_ window: NSWindow) {
|
||||||
guard self.window !== window else { return }
|
guard self.window !== window else { return }
|
||||||
self.window = window
|
self.window = window
|
||||||
window.title = fileName ?? "terebi"
|
window.title = fileName ?? "Terebi"
|
||||||
window.contentMinSize = NSSize(width: 400, height: 240)
|
window.contentMinSize = NSSize(width: 400, height: 240)
|
||||||
compactWindow.normalVideoLayout = { [weak self] in
|
compactWindow.normalVideoLayout = { [weak self] in
|
||||||
guard let self, self.showsQueue, self.state.has_video else { return nil }
|
guard let self, self.showsQueue, self.state.has_video else { return nil }
|
||||||
@@ -1978,7 +1978,7 @@ private struct PlayerContent: View {
|
|||||||
|
|
||||||
private func compactTitleLabel(progress: String?, constrained: Bool) -> some View {
|
private func compactTitleLabel(progress: String?, constrained: Bool) -> some View {
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
Text(model.fileName ?? "terebi")
|
Text(model.fileName ?? "Terebi")
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.truncationMode(.tail)
|
.truncationMode(.tail)
|
||||||
.frame(minWidth: 0, maxWidth: constrained ? .infinity : nil, alignment: .leading)
|
.frame(minWidth: 0, maxWidth: constrained ? .infinity : nil, alignment: .leading)
|
||||||
@@ -2069,11 +2069,11 @@ private struct PlayerContent: View {
|
|||||||
} else {
|
} else {
|
||||||
Image(systemName: "play.rectangle.fill").font(.system(size: 14))
|
Image(systemName: "play.rectangle.fill").font(.system(size: 14))
|
||||||
}
|
}
|
||||||
Text(model.fileName ?? "terebi")
|
Text(model.fileName ?? "Terebi")
|
||||||
.font(.system(size: 13, weight: .semibold))
|
.font(.system(size: 13, weight: .semibold))
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
.truncationMode(.tail)
|
.truncationMode(.tail)
|
||||||
.help(model.fileName ?? "terebi")
|
.help(model.fileName ?? "Terebi")
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 8)
|
.padding(.horizontal, 8)
|
||||||
.frame(height: 24)
|
.frame(height: 24)
|
||||||
@@ -2491,7 +2491,7 @@ private struct PlayerContent: View {
|
|||||||
.foregroundStyle(Color(SunsetPalette.accent))
|
.foregroundStyle(Color(SunsetPalette.accent))
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
Text("terebi").font(.system(size: 20, weight: .semibold))
|
Text("Terebi").font(.system(size: 20, weight: .semibold))
|
||||||
.foregroundStyle(Color(SunsetPalette.text))
|
.foregroundStyle(Color(SunsetPalette.text))
|
||||||
Text("Open media to get started")
|
Text("Open media to get started")
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
@@ -2603,7 +2603,7 @@ private struct PlayerContent: View {
|
|||||||
}
|
}
|
||||||
.font(.system(size: 11, weight: .medium))
|
.font(.system(size: 11, weight: .medium))
|
||||||
.accessibilityElement(children: .combine)
|
.accessibilityElement(children: .combine)
|
||||||
.help((model.fileName ?? "terebi") + (progress.map { " · \($0)" } ?? ""))
|
.help((model.fileName ?? "Terebi") + (progress.map { " · \($0)" } ?? ""))
|
||||||
.padding(.horizontal, 8)
|
.padding(.horizontal, 8)
|
||||||
.frame(height: 28)
|
.frame(height: 28)
|
||||||
.background(PlayerGlass(cornerRadius: 10).clipShape(RoundedRectangle(cornerRadius: 10)).allowsHitTesting(false))
|
.background(PlayerGlass(cornerRadius: 10).clipShape(RoundedRectangle(cornerRadius: 10)).allowsHitTesting(false))
|
||||||
@@ -2848,7 +2848,7 @@ struct TerebiApp: App {
|
|||||||
@StateObject private var model = PlayerModel.shared
|
@StateObject private var model = PlayerModel.shared
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
Window("\(model.fileName ?? "terebi")", id: "terebi") {
|
Window("\(model.fileName ?? "Terebi")", id: "terebi") {
|
||||||
PlayerContent(model: model)
|
PlayerContent(model: model)
|
||||||
.focusedSceneObject(model)
|
.focusedSceneObject(model)
|
||||||
}
|
}
|
||||||
@@ -2874,7 +2874,7 @@ public func terebiAppMain() {
|
|||||||
NSApp.activate(ignoringOtherApps: true)
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
let alert = NSAlert()
|
let alert = NSAlert()
|
||||||
alert.alertStyle = .critical
|
alert.alertStyle = .critical
|
||||||
alert.messageText = "Could not load terebi configuration"
|
alert.messageText = "Could not load Terebi configuration"
|
||||||
alert.informativeText = error.localizedDescription
|
alert.informativeText = error.localizedDescription
|
||||||
alert.runModal()
|
alert.runModal()
|
||||||
exit(78)
|
exit(78)
|
||||||
|
|||||||
Reference in New Issue
Block a user