Skip to content

Commit 6e31563

Browse files
committed
Merged with master
2 parents 0b9863c + d57b449 commit 6e31563

File tree

10 files changed

+162
-17
lines changed

10 files changed

+162
-17
lines changed

Packages/ConfCore/ConfCore/StorageMigrator.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ final class StorageMigrator {
2727
32: migrateSessionModels,
2828
34: migrateOldTranscriptModels,
2929
37: migrateIdentifiersWithoutReplacement,
30-
43: migrateTracks,
30+
43: resetTracks,
3131
44: removeInvalidLiveAssets,
32-
57: resetFeaturedSections
32+
57: resetFeaturedSections,
33+
59: resetTracks
3334
]
3435

3536
init(migration: Migration, oldVersion: UInt64) {
@@ -162,8 +163,8 @@ final class StorageMigrator {
162163
}
163164
}
164165

165-
private static func migrateTracks(with migration: Migration, oldVersion: SchemaVersion, log: OSLog) {
166-
os_log("migrateTracks", log: log, type: .info)
166+
private static func resetTracks(with migration: Migration, oldVersion: SchemaVersion, log: OSLog) {
167+
os_log("resetTracks", log: log, type: .info)
167168

168169
migration.deleteData(forType: "Track")
169170
}

WWDC.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@
187187
F4578D9F2A26A218005B311A /* WWDCAppCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4578D9E2A26A218005B311A /* WWDCAppCommand.swift */; };
188188
F474DEC926737EFA00B28B31 /* SharePlayManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F474DEC826737EFA00B28B31 /* SharePlayManager.swift */; };
189189
F474DECD2673801500B28B31 /* WatchWWDCActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = F474DECC2673801500B28B31 /* WatchWWDCActivity.swift */; };
190+
F4777ABA2A2A2F6C00A09179 /* WWDCAgentRemover.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4777AB92A2A2F6C00A09179 /* WWDCAgentRemover.swift */; };
190191
F4A882842673AC8500BAB7F5 /* TitleBarButtonsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4A882832673AC8500BAB7F5 /* TitleBarButtonsViewController.swift */; };
191192
F4A882882673AD2D00BAB7F5 /* SharePlayStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4A882862673AD2D00BAB7F5 /* SharePlayStatusView.swift */; };
192193
F4CCF942265ED24500A69E62 /* AppCommandsReceiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CCF941265ED24500A69E62 /* AppCommandsReceiver.swift */; };
@@ -455,6 +456,7 @@
455456
F4578D9E2A26A218005B311A /* WWDCAppCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WWDCAppCommand.swift; sourceTree = "<group>"; };
456457
F474DEC826737EFA00B28B31 /* SharePlayManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharePlayManager.swift; sourceTree = "<group>"; };
457458
F474DECC2673801500B28B31 /* WatchWWDCActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchWWDCActivity.swift; sourceTree = "<group>"; };
459+
F4777AB92A2A2F6C00A09179 /* WWDCAgentRemover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WWDCAgentRemover.swift; sourceTree = "<group>"; };
458460
F4A882832673AC8500BAB7F5 /* TitleBarButtonsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleBarButtonsViewController.swift; sourceTree = "<group>"; };
459461
F4A882862673AD2D00BAB7F5 /* SharePlayStatusView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharePlayStatusView.swift; sourceTree = "<group>"; };
460462
F4CCF941265ED24500A69E62 /* AppCommandsReceiver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCommandsReceiver.swift; sourceTree = "<group>"; };
@@ -593,6 +595,7 @@
593595
children = (
594596
01B3EB491EEDD23100DE1003 /* AppCoordinator+SessionTableViewContextMenuActions.swift */,
595597
DDA50E3424AA5090007C77C6 /* Boot.swift */,
598+
F4777AB92A2A2F6C00A09179 /* WWDCAgentRemover.swift */,
596599
DD36A4AF1E478C6A00B2EA88 /* AppDelegate.swift */,
597600
DDCE7ED81EA7A86600C7A3CA /* AppCoordinator.swift */,
598601
F4CCF941265ED24500A69E62 /* AppCommandsReceiver.swift */,
@@ -1407,6 +1410,7 @@
14071410
DDF32EAB1EBE2E240028E39D /* WWDCTableRowView.swift in Sources */,
14081411
DD7E2902247FEA3900A58370 /* EventHeroViewController.swift in Sources */,
14091412
DDC927FE20B7A259004C784D /* NSImage+Compression.swift in Sources */,
1413+
F4777ABA2A2A2F6C00A09179 /* WWDCAgentRemover.swift in Sources */,
14101414
DD7A2103218111470052FD07 /* WWDCProgressIndicator.swift in Sources */,
14111415
DD7F38681EABE4E4002D8C00 /* SessionViewModel.swift in Sources */,
14121416
DD9564231ED27FBE00051D07 /* NSImage+Thumbnail.swift in Sources */,

WWDC/Boot.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ final class Boot {
5151
return
5252
}
5353

54+
WWDCAgentRemover.removeWWDCAgentIfNeeded()
55+
5456
do {
5557
let supportPath = try PathUtil.appSupportPathCreatingIfNeeded()
5658
let filePath = supportPath + "/ConfCore.realm"

WWDC/Constants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foundation
1010

1111
struct Constants {
1212

13-
static let coreSchemaVersion: UInt64 = 58
13+
static let coreSchemaVersion: UInt64 = 59
1414

1515
static let thumbnailHeight: CGFloat = 150
1616

WWDC/ExploreTabContent.swift

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,47 @@ extension ExploreTabContent.Item {
7272
imageURL: URL(string: "https://wwdc.io/images/placeholder.jpg")!
7373
)
7474
]
75+
static let placeholderItems2: [ExploreTabContent.Item] = [
76+
.init(
77+
id: "4",
78+
title: "Placeholder Item Regular",
79+
subtitle: "Placeholder Description 4",
80+
overlayText: "24m",
81+
overlaySymbol: "play",
82+
imageURL: URL(string: "https://wwdc.io/images/placeholder.jpg")!
83+
),
84+
.init(
85+
id: "5",
86+
title: "Placeholder",
87+
subtitle: "Placeholder Item Description 5",
88+
overlayText: "37m",
89+
overlaySymbol: "play",
90+
imageURL: URL(string: "https://wwdc.io/images/placeholder.jpg")!
91+
),
92+
.init(
93+
id: "6",
94+
title: "Placeholder Item Longer Title",
95+
subtitle: "Placeholder Item Description 6",
96+
overlayText: "37m",
97+
overlaySymbol: "play",
98+
imageURL: URL(string: "https://wwdc.io/images/placeholder.jpg")!
99+
),
100+
.init(
101+
id: "7",
102+
title: "Placeholder",
103+
subtitle: "Item Description 7",
104+
overlayText: "35m",
105+
overlaySymbol: "play",
106+
imageURL: URL(string: "https://wwdc.io/images/placeholder.jpg")!
107+
)
108+
]
75109
}
76110

77111
extension ExploreTabContent {
78112
static let placeholder: ExploreTabContent = {
79113
ExploreTabContent(id: "1", sections: [
80114
Section(id: "placeholder-1", title: "Placeholder Section First", icon: .symbol("app.badge.checkmark"), items: ExploreTabContent.Item.placeholderItems),
81-
Section(id: "placeholder-2", title: "Placeholder Section Second Longer Title", icon: .symbol("app.badge.checkmark"), items: ExploreTabContent.Item.placeholderItems),
115+
Section(id: "placeholder-2", title: "Placeholder Section Second Longer Title", icon: .symbol("app.badge.checkmark"), items: ExploreTabContent.Item.placeholderItems2),
82116
Section(id: "placeholder-3", title: "Placeholder Short", icon: .symbol("app.badge.checkmark"), items: ExploreTabContent.Item.placeholderItems)
83117
])
84118
}()

WWDC/ExploreTabItemView.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ struct ExploreTabItemView: View {
2727
item.progress != nil ? .topTrailing : .bottomTrailing
2828
}
2929

30-
private var hasOverlay: Bool { item.overlayText != nil || item.overlaySymbol != nil }
30+
@Environment(\.redactionReasons)
31+
private var redactionReasons
32+
33+
private var hasOverlay: Bool {
34+
guard redactionReasons.isEmpty else { return false }
35+
return item.overlayText != nil || item.overlaySymbol != nil
36+
}
3137

3238
var body: some View {
3339
VStack(alignment: .leading, spacing: 8) {

WWDC/ExploreTabProvider.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ final class ExploreTabProvider: ObservableObject {
7171

7272
private var disposeBag = DisposeBag()
7373

74-
private struct SourceData {
74+
fileprivate struct SourceData {
7575
var featuredSections: Results<FeaturedSection>
7676
var continueWatching: [Session]
7777
var recentFavorites: [Session]
@@ -101,6 +101,8 @@ final class ExploreTabProvider: ObservableObject {
101101
}
102102

103103
private func update(with data: SourceData) {
104+
guard !data.shouldDisplayPlaceholderUI else { return }
105+
104106
let continueWatchingSection = ExploreTabContent.Section(
105107
id: "continue-watching",
106108
title: "Continue Watching",
@@ -293,3 +295,15 @@ extension WWDCFiltersState {
293295
)
294296
}
295297
}
298+
299+
private extension ExploreTabProvider.SourceData {
300+
/// `true` when all sections except for "Topics" are empty.
301+
/// This addresses migration from previous versions without an Explore tab,
302+
/// where the local database has topics but no other data relevant to the explore tab.
303+
var shouldDisplayPlaceholderUI: Bool {
304+
featuredSections.isEmpty
305+
&& continueWatching.isEmpty
306+
&& recentFavorites.isEmpty
307+
&& liveEventSession == nil
308+
}
309+
}

WWDC/ExploreTabRootView.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@ struct ExploreTabRootView: View {
44
@EnvironmentObject private var provider: ExploreTabProvider
55

66
var body: some View {
7-
if let content = provider.content {
8-
ExploreTabContentView(content: content, scrollOffset: $provider.scrollOffset)
9-
#if DEBUG
10-
.contextMenu { Button("Export JSON…", action: content.exportJSON) }
11-
#endif
12-
} else {
13-
ExploreTabContentView(content: .placeholder, scrollOffset: .constant(.zero))
14-
.redacted(reason: .placeholder)
7+
ZStack {
8+
if let content = provider.content {
9+
ExploreTabContentView(content: content, scrollOffset: $provider.scrollOffset)
10+
#if DEBUG
11+
.contextMenu { Button("Export JSON…", action: content.exportJSON) }
12+
#endif
13+
} else {
14+
ExploreTabContentView(content: .placeholder, scrollOffset: .constant(.zero))
15+
.redacted(reason: .placeholder)
16+
}
1517
}
18+
.animation(.spring(), value: provider.content?.sections.flatMap(\.items).count)
1619
}
1720

1821
}

WWDC/Main.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "TeamID.xcconfig"
44

55
MARKETING_VERSION = 7.4
6-
CURRENT_PROJECT_VERSION = 1034
6+
CURRENT_PROJECT_VERSION = 1036
77

88
MACOSX_DEPLOYMENT_TARGET = 12.0
99

WWDC/WWDCAgentRemover.swift

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import Cocoa
2+
import OSLog
3+
4+
/// Handles removal of the legacy `WWDCAgent` helper process,
5+
/// which is no longer available but may cause database migration
6+
/// issues on first launch of version 7.4.
7+
struct WWDCAgentRemover {
8+
9+
private static let logger = Logger(subsystem: "io.wwdc.app", category: "WWDCAgentRemover")
10+
11+
private static let agentBundleID = "io.wwdc.app.WWDCAgent"
12+
13+
private static let agentLaunchdServiceID: String = { "gui/\(getuid())/\(agentBundleID)" }()
14+
15+
private static var performedLegacyAgentRemoval: Bool {
16+
get { UserDefaults.standard.bool(forKey: #function) }
17+
set {
18+
UserDefaults.standard.set(newValue, forKey: #function)
19+
UserDefaults.standard.synchronize()
20+
}
21+
}
22+
23+
static func removeWWDCAgentIfNeeded() {
24+
guard !performedLegacyAgentRemoval else { return }
25+
26+
/// Set the flag regardless of the removal result.
27+
/// The idea is to avoid potential launch issues caused
28+
/// by repeated attempts in case removal fails for some obscure reason.
29+
defer { performedLegacyAgentRemoval = true }
30+
31+
guard let agent = NSRunningApplication.runningApplications(withBundleIdentifier: agentBundleID).first else {
32+
logger.debug("Couldn't find \(agentBundleID, privacy: .public) process, skipping legacy agent removal")
33+
return
34+
}
35+
36+
unregisterAgent()
37+
38+
guard !agent.isTerminated else {
39+
logger.debug("Legacy agent process is present, but already terminated")
40+
return
41+
}
42+
43+
if !agent.forceTerminate() {
44+
logger.warning("Force terminate failed for \(agentBundleID, privacy: .public)")
45+
} else {
46+
logger.debug("Successfully terminated legacy agent")
47+
}
48+
}
49+
50+
private static func unregisterAgent() {
51+
logger.debug("Requesting removal of service \(agentLaunchdServiceID, privacy: .public)")
52+
53+
let proc = Process()
54+
proc.executableURL = URL(fileURLWithPath: "/bin/launchctl")
55+
proc.arguments = [
56+
"bootout",
57+
agentLaunchdServiceID
58+
]
59+
let outPipe = Pipe()
60+
let errPipe = Pipe()
61+
proc.standardOutput = outPipe
62+
proc.standardError = errPipe
63+
64+
do {
65+
try proc.run()
66+
67+
proc.waitUntilExit()
68+
69+
guard proc.terminationStatus == 0 else {
70+
let output = (try? errPipe.fileHandleForReading.readToEnd().flatMap { String(decoding: $0, as: UTF8.self) }) ?? "<nil>"
71+
logger.error("launchctl operation failed with exit code \(proc.terminationStatus, privacy: .public): \(output, privacy: .public)")
72+
return
73+
}
74+
75+
logger.debug("launchctl operation succeeded")
76+
} catch {
77+
logger.fault("Failed to run launchctl: \(error, privacy: .public)")
78+
}
79+
}
80+
81+
}

0 commit comments

Comments
 (0)