소스 검색

Expand Google Drive desktop widget shortcuts and fix query URLs.

Redesign Drive variants: small row for Recent, My Drive, and Search; medium
adds shared files and New Doc; large hub adds shared drives, create links
for Docs/Sheets/Slides, type filters (PDF, image, video), storage, and
Drive settings.

Allow large Drive widgets up to 15 actions (same cap as Gmail). Parse
relative paths with both query strings and hash fragments in resolvedURL.

Made-with: Cursor
huzaifahayat12 3 달 전
부모
커밋
2e54474543
2개의 변경된 파일40개의 추가작업 그리고 14개의 파일을 삭제
  1. 21 6
      google_apps/Widgets/DesktopWidgetView.swift
  2. 19 8
      google_apps/Widgets/WidgetTemplates.swift

+ 21 - 6
google_apps/Widgets/DesktopWidgetView.swift

@@ -98,8 +98,10 @@ struct DesktopWidgetView: View {
         case .small: return 3
         case .medium: return 4
         case .large:
-            if WidgetAppProfile.from(app: app) == .gmail { return 15 }
-            return 8
+            switch WidgetAppProfile.from(app: app) {
+            case .gmail, .drive: return 15
+            default: return 8
+            }
         }
     }
 
@@ -208,13 +210,26 @@ struct DesktopWidgetView: View {
         }
         if substituted.hasPrefix("/") {
             var c = URLComponents(url: base, resolvingAgainstBaseURL: false)
+            let pathAndQuery: String
+            let fragmentPart: String?
             if let hashIdx = substituted.firstIndex(of: "#") {
-                let pathPart = String(substituted[..<hashIdx])
-                let fragPart = String(substituted[substituted.index(after: hashIdx)...])
+                pathAndQuery = String(substituted[..<hashIdx])
+                fragmentPart = String(substituted[substituted.index(after: hashIdx)...])
+            } else {
+                pathAndQuery = substituted
+                fragmentPart = nil
+            }
+            if let qIdx = pathAndQuery.firstIndex(of: "?") {
+                let pathPart = String(pathAndQuery[..<qIdx])
+                let queryPart = String(pathAndQuery[pathAndQuery.index(after: qIdx)...])
                 c?.path = pathPart
-                c?.fragment = fragPart.isEmpty ? nil : String(fragPart)
+                c?.query = queryPart
+            } else {
+                c?.path = pathAndQuery
+            }
+            if let fragmentPart, !fragmentPart.isEmpty {
+                c?.fragment = String(fragmentPart)
             } else {
-                c?.path = substituted
                 c?.fragment = nil
             }
             return c?.url ?? base

+ 19 - 8
google_apps/Widgets/WidgetTemplates.swift

@@ -88,22 +88,33 @@ enum WidgetTemplates {
             ]
         case .drive:
             return [
-                v("drive_small", "My Drive", .small, false, .iconOnly(title: "My Drive"), [a("mydrive", "Open", "externaldrive.fill", "/drive/my-drive")]),
-                v("drive_medium", "Drive Shortcuts", .medium, true, .actionsGrid(columns: 2), [
+                v("drive_small", "Quick access", .small, false, .actionsRow, [
+                    a("recent", "Recent", "clock.arrow.circlepath", "/drive/recent"),
+                    a("mydrive", "My Drive", "externaldrive.fill", "/drive/my-drive"),
+                    a("search", "Search", "magnifyingglass", "/drive/search"),
+                ]),
+                v("drive_medium", "Files & sharing", .medium, true, .actionsGrid(columns: 2), [
                     a("mydrive", "My Drive", "externaldrive.fill", "/drive/my-drive"),
-                    a("shared", "Shared", "person.2", "/drive/shared-with-me"),
                     a("recent", "Recent", "clock.arrow.circlepath", "/drive/recent"),
-                    a("starred", "Starred", "star", "/drive/starred"),
+                    a("shared", "Shared", "person.2", "/drive/shared-with-me"),
+                    a("newdoc", "New Doc", "doc.text", "https://docs.google.com/document/create"),
                 ]),
-                v("drive_large", "Drive Hub", .large, true, .actionsGrid(columns: 2), [
+                v("drive_large", "Drive hub", .large, true, .actionsGrid(columns: 2), [
                     a("mydrive", "My Drive", "externaldrive.fill", "/drive/my-drive"),
-                    a("shared", "Shared with me", "person.2", "/drive/shared-with-me"),
                     a("recent", "Recent", "clock.arrow.circlepath", "/drive/recent"),
+                    a("search", "Search", "magnifyingglass", "/drive/search"),
+                    a("shared", "Shared", "person.2", "/drive/shared-with-me"),
+                    a("shareddrives", "Shared drives", "person.3.fill", "/drive/shared-drives"),
                     a("starred", "Starred", "star", "/drive/starred"),
+                    a("newdoc", "New Doc", "doc.text.fill", "https://docs.google.com/document/create"),
+                    a("newsheet", "New Sheet", "tablecells.fill", "https://sheets.google.com/spreadsheets/create"),
+                    a("newslide", "New Slides", "rectangle.on.rectangle.fill", "https://slides.google.com/presentation/create"),
+                    a("pdfs", "PDFs", "doc.text.fill", "/drive/search?q=type:pdf"),
+                    a("images", "Images", "photo", "/drive/search?q=type:image"),
+                    a("videos", "Videos", "film", "/drive/search?q=type:video"),
                     a("trash", "Trash", "trash", "/drive/trash"),
                     a("storage", "Storage", "internaldrive", "/settings/storage"),
-                    a("search", "Search", "magnifyingglass", "/drive/search"),
-                    a("computers", "Computers", "desktopcomputer", "/drive/computers"),
+                    a("settings", "Settings", "gearshape", "/drive/settings"),
                 ]),
             ]
         case .docs: