shortcuts.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import WidgetKit
  2. import SwiftUI
  3. struct Provider: TimelineProvider {
  4. func placeholder(in context: Context) -> SimpleEntry {
  5. SimpleEntry(date: Date())
  6. }
  7. func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
  8. let entry = SimpleEntry(date: Date())
  9. completion(entry)
  10. }
  11. func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
  12. let currentDate = Date()
  13. let entry = SimpleEntry(date: currentDate)
  14. let timeline = Timeline(entries: [entry], policy: .atEnd)
  15. completion(timeline)
  16. }
  17. }
  18. struct SimpleEntry: TimelineEntry {
  19. let date: Date
  20. }
  21. struct ShortcutsEntryView: View {
  22. var entry: Provider.Entry
  23. // Format weekday name (e.g., "Monday")
  24. private var weekday: String {
  25. let formatter = DateFormatter()
  26. formatter.locale = Locale.current // ✅ respect user’s locale
  27. formatter.dateFormat = "EEEE" // full weekday name
  28. return formatter.string(from: Date())
  29. }
  30. var body: some View {
  31. Link(destination: URL(string: "logseq://mobile/go/quick-add")!) {
  32. VStack(alignment: .leading, spacing: 0) {
  33. // Top heading
  34. Link(destination: URL(string: "logseq://mobile")!) {
  35. HStack(alignment: .top, spacing: 8) {
  36. Text(weekday)
  37. .font(.subheadline)
  38. .bold()
  39. .foregroundColor(.white.opacity(0.5))
  40. .padding(.top, 4)
  41. Spacer()
  42. Image("LogseqLogo")
  43. .resizable()
  44. .scaledToFit()
  45. .frame(width: 30, height: 30)
  46. }
  47. }
  48. // Middle text
  49. Text("I have an idea...")
  50. .font(.headline)
  51. .bold()
  52. .foregroundColor(.white.opacity(0.8))
  53. Spacer(minLength: 0)
  54. // Bottom buttons row
  55. HStack(spacing: 8) {
  56. // Left button (audio waves)
  57. Link(destination: URL(string: "logseq://mobile/go/audio")!) {
  58. Image(systemName: "waveform")
  59. .font(.body)
  60. .foregroundColor(.white)
  61. .frame(maxWidth: .infinity, minHeight: 36)
  62. .background(Color.white.opacity(0.1))
  63. .clipShape(Capsule())
  64. .contentShape(Capsule())
  65. }
  66. // Right button (quick add)
  67. Link(destination: URL(string: "logseq://mobile/go/quick-add")!) {
  68. Image(systemName: "plus")
  69. .font(.body)
  70. .foregroundColor(.white)
  71. .frame(maxWidth: .infinity, minHeight: 36)
  72. .background(Color.white.opacity(0.1))
  73. .clipShape(Capsule())
  74. .contentShape(Capsule())
  75. }
  76. }
  77. }
  78. .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
  79. .padding(-8)
  80. }
  81. }
  82. }
  83. // Helper to support hex colors
  84. extension Color {
  85. init(hex: String) {
  86. let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
  87. var int: UInt64 = 0
  88. Scanner(string: hex).scanHexInt64(&int)
  89. let a, r, g, b: UInt64
  90. switch hex.count {
  91. case 3:
  92. (a, r, g, b) = (255,
  93. (int >> 8) * 17,
  94. (int >> 4 & 0xF) * 17,
  95. (int & 0xF) * 17)
  96. case 6:
  97. (a, r, g, b) = (255,
  98. int >> 16,
  99. int >> 8 & 0xFF,
  100. int & 0xFF)
  101. case 8:
  102. (a, r, g, b) = (int >> 24,
  103. int >> 16 & 0xFF,
  104. int >> 8 & 0xFF,
  105. int & 0xFF)
  106. default:
  107. (a, r, g, b) = (255, 0, 0, 0)
  108. }
  109. self.init(
  110. .sRGB,
  111. red: Double(r) / 255,
  112. green: Double(g) / 255,
  113. blue: Double(b) / 255,
  114. opacity: Double(a) / 255
  115. )
  116. }
  117. }
  118. struct Shortcuts: Widget {
  119. let kind: String = "shortcuts"
  120. var body: some WidgetConfiguration {
  121. StaticConfiguration(kind: kind, provider: Provider()) { entry in
  122. if #available(iOS 17.0, *) {
  123. ShortcutsEntryView(entry: entry)
  124. .containerBackground(Color(hex: "#002b36"), for: .widget)
  125. } else {
  126. ZStack {
  127. Color(hex: "#002b36")
  128. ShortcutsEntryView(entry: entry)
  129. }
  130. }
  131. }
  132. .configurationDisplayName("Logseq Shortcuts")
  133. .description("Quick actions for Logseq")
  134. }
  135. }
  136. #Preview(as: .systemSmall) {
  137. Shortcuts()
  138. } timeline: {
  139. SimpleEntry(date: .now)
  140. }