mirror of
https://github.com/abue-ammar/tinycast.git
synced 2026-10-02 08:14:38 +08:00
code review fix
This commit is contained in:
@@ -148,6 +148,8 @@ enum CalcDateTime {
|
||||
|
||||
// C: moment ± duration → a new moment.
|
||||
if let duration = parseDurationPhrase(right) {
|
||||
// Negating Int.min traps; degrade to no card on that edge.
|
||||
guard op == "+" || duration.count != .min else { return nil }
|
||||
let signed = op == "-" ? -duration.count : duration.count
|
||||
guard
|
||||
let result = calendar.date(
|
||||
@@ -255,7 +257,9 @@ enum CalcDateTime {
|
||||
calendar: calendar)
|
||||
}
|
||||
if let month = monthByName[b] {
|
||||
return monthDayMoment(month: month, day: 1, now: now, calendar: calendar)
|
||||
return monthDayMoment(
|
||||
month: month, day: 1, now: now, calendar: calendar,
|
||||
bias: a == "last" ? .past : .future)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -387,7 +391,10 @@ enum CalcDateTime {
|
||||
case "min", "mins", "minute", "minutes": return (count, .minute, true)
|
||||
case "h", "hr", "hrs", "hour", "hours": return (count, .hour, true)
|
||||
case "d", "day", "days": return (count, .day, false)
|
||||
case "wk", "week", "weeks": return (count * 7, .day, false)
|
||||
case "wk", "week", "weeks":
|
||||
// Absurd counts overflow the fold to days; degrade to no card rather than trap.
|
||||
let (days, overflow) = count.multipliedReportingOverflow(by: 7)
|
||||
return overflow ? nil : (days, .day, false)
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,10 +330,11 @@ final class ClipboardStore: ObservableObject {
|
||||
let cutoff = Date().addingTimeInterval(-maxAge)
|
||||
if let imagesStmt = staleImagesStmt, let deleteStmt = deleteStaleStmt {
|
||||
sqlite3_bind_double(imagesStmt, 1, cutoff.timeIntervalSince1970)
|
||||
var staleOwnedPaths: [String] = []
|
||||
while sqlite3_step(imagesStmt) == SQLITE_ROW {
|
||||
// Only delete files we own; external references (e.g. imported) just lose their row.
|
||||
if let path = Self.columnString(imagesStmt, 0), owns(path) {
|
||||
try? FileManager.default.removeItem(atPath: path)
|
||||
staleOwnedPaths.append(path)
|
||||
}
|
||||
}
|
||||
sqlite3_reset(imagesStmt)
|
||||
@@ -342,6 +343,14 @@ final class ClipboardStore: ObservableObject {
|
||||
sqlite3_step(deleteStmt)
|
||||
sqlite3_reset(deleteStmt)
|
||||
sqlite3_clear_bindings(deleteStmt)
|
||||
// A retention cut can strand hundreds of files; delete them off the main actor so capture-time prune doesn't hitch.
|
||||
if !staleOwnedPaths.isEmpty {
|
||||
Task.detached(priority: .utility) {
|
||||
for path in staleOwnedPaths {
|
||||
try? FileManager.default.removeItem(atPath: path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if items.last.map({ $0.createdAt < cutoff }) == true {
|
||||
items.removeAll { $0.createdAt < cutoff }
|
||||
|
||||
@@ -790,6 +790,14 @@ struct EmptyResults: View {
|
||||
enum CompactFavoriteSlot {
|
||||
case app(AppEntry)
|
||||
case more
|
||||
|
||||
// Stable identity so a slot keeps its icon tied to its app, not its position, when favorites reorder.
|
||||
var id: String {
|
||||
switch self {
|
||||
case .app(let app): return app.id
|
||||
case .more: return "__tinycast.more__"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The compact bar's favorites strip — up to 5 icon buttons, ⌘1–⌘5 mirrored in each tooltip.
|
||||
@@ -800,7 +808,7 @@ private struct CompactFavoritesRow: View {
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: Theme.Spacing.xs) {
|
||||
ForEach(Array(slots.enumerated()), id: \.offset) { index, slot in
|
||||
ForEach(Array(slots.enumerated()), id: \.element.id) { index, slot in
|
||||
switch slot {
|
||||
case .app(let app):
|
||||
CompactFavoriteButton(help: "\(app.name) ⌘\(index + 1)") {
|
||||
|
||||
Reference in New Issue
Block a user