|
|
@@ -32,13 +32,11 @@ struct WidgetVariant: Identifiable, Hashable {
|
|
|
|
|
|
enum WidgetTemplates {
|
|
|
static func variants(for app: LauncherApp) -> [WidgetVariant] {
|
|
|
- let base = app.webURL
|
|
|
-
|
|
|
func v(_ id: String, _ title: String, _ size: WidgetSize, _ showHeader: Bool, _ layout: WidgetLayoutMode, _ actions: [WidgetAction]) -> WidgetVariant {
|
|
|
WidgetVariant(id: id, title: title, size: size, showHeader: showHeader, layoutMode: layout, actions: actions)
|
|
|
}
|
|
|
|
|
|
- let profile = appProfile(for: app)
|
|
|
+ let profile = WidgetAppProfile.from(app: app)
|
|
|
switch profile {
|
|
|
case .photos:
|
|
|
return [
|
|
|
@@ -80,15 +78,105 @@ enum WidgetTemplates {
|
|
|
]),
|
|
|
]
|
|
|
case .drive:
|
|
|
- return contentWorkspaceVariants(prefix: "drive", appName: "Drive", rootPath: "/drive/my-drive", searchPath: "/drive/search")
|
|
|
+ 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), [
|
|
|
+ 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"),
|
|
|
+ ]),
|
|
|
+ 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("starred", "Starred", "star", "/drive/starred"),
|
|
|
+ a("trash", "Trash", "trash", "/drive/trash"),
|
|
|
+ a("storage", "Storage", "internaldrive", "/settings/storage"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/drive/search"),
|
|
|
+ a("computers", "Computers", "desktopcomputer", "/drive/computers"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .docs:
|
|
|
- return contentWorkspaceVariants(prefix: "docs", appName: "Docs", rootPath: "/document/u/0/", searchPath: "/document/u/0/")
|
|
|
+ return [
|
|
|
+ v("docs_small", "Docs", .small, false, .iconOnly(title: "Docs"), [a("home", "Open", "doc.text.fill", "/document/u/0/")]),
|
|
|
+ v("docs_medium", "Docs Shortcuts", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/document/u/0/"),
|
|
|
+ a("new", "New doc", "plus", "/document/create"),
|
|
|
+ a("templates", "Templates", "square.grid.2x2", "/document/u/0/templates/home"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/document/u/0/search"),
|
|
|
+ ]),
|
|
|
+ v("docs_large", "Docs Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/document/u/0/"),
|
|
|
+ a("new", "New doc", "plus", "/document/create"),
|
|
|
+ a("templates", "Templates", "square.grid.2x2", "/document/u/0/templates/home"),
|
|
|
+ a("starred", "Starred", "star", "/document/u/0/starred"),
|
|
|
+ a("shared", "Shared", "person.2", "/document/u/0/shared-with-me"),
|
|
|
+ a("trash", "Trash", "trash", "/document/u/0/trash"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/document/u/0/search"),
|
|
|
+ a("offline", "Offline", "arrow.down.circle", "/document/u/0/offline"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .sheets:
|
|
|
- return contentWorkspaceVariants(prefix: "sheets", appName: "Sheets", rootPath: "/spreadsheets/u/0/", searchPath: "/spreadsheets/u/0/")
|
|
|
+ return [
|
|
|
+ v("sheets_small", "Sheets", .small, false, .iconOnly(title: "Sheets"), [a("home", "Open", "tablecells.fill", "/spreadsheets/u/0/")]),
|
|
|
+ v("sheets_medium", "Sheets Shortcuts", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/spreadsheets/u/0/"),
|
|
|
+ a("new", "New sheet", "plus", "/spreadsheets/create"),
|
|
|
+ a("templates", "Templates", "square.grid.2x2", "/spreadsheets/u/0/templates"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/spreadsheets/u/0/search"),
|
|
|
+ ]),
|
|
|
+ v("sheets_large", "Sheets Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/spreadsheets/u/0/"),
|
|
|
+ a("new", "New sheet", "plus", "/spreadsheets/create"),
|
|
|
+ a("templates", "Templates", "square.grid.2x2", "/spreadsheets/u/0/templates"),
|
|
|
+ a("starred", "Starred", "star", "/spreadsheets/u/0/starred"),
|
|
|
+ a("shared", "Shared", "person.2", "/spreadsheets/u/0/shared-with-me"),
|
|
|
+ a("trash", "Trash", "trash", "/spreadsheets/u/0/trash"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/spreadsheets/u/0/search"),
|
|
|
+ a("offline", "Offline", "arrow.down.circle", "/spreadsheets/u/0/offline"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .slides:
|
|
|
- return contentWorkspaceVariants(prefix: "slides", appName: "Slides", rootPath: "/presentation/u/0/", searchPath: "/presentation/u/0/")
|
|
|
+ return [
|
|
|
+ v("slides_small", "Slides", .small, false, .iconOnly(title: "Slides"), [a("home", "Open", "rectangle.on.rectangle.fill", "/presentation/u/0/")]),
|
|
|
+ v("slides_medium", "Slides Shortcuts", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/presentation/u/0/"),
|
|
|
+ a("new", "New deck", "plus", "/presentation/create"),
|
|
|
+ a("templates", "Templates", "square.grid.2x2", "/presentation/u/0/templates"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/presentation/u/0/search"),
|
|
|
+ ]),
|
|
|
+ v("slides_large", "Slides Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/presentation/u/0/"),
|
|
|
+ a("new", "New deck", "plus", "/presentation/create"),
|
|
|
+ a("templates", "Templates", "square.grid.2x2", "/presentation/u/0/templates"),
|
|
|
+ a("starred", "Starred", "star", "/presentation/u/0/starred"),
|
|
|
+ a("shared", "Shared", "person.2", "/presentation/u/0/shared-with-me"),
|
|
|
+ a("trash", "Trash", "trash", "/presentation/u/0/trash"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/presentation/u/0/search"),
|
|
|
+ a("offline", "Offline", "arrow.down.circle", "/presentation/u/0/offline"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .forms:
|
|
|
- return contentWorkspaceVariants(prefix: "forms", appName: "Forms", rootPath: "/forms/u/0/", searchPath: "/forms/u/0/")
|
|
|
+ return [
|
|
|
+ v("forms_small", "Forms", .small, false, .iconOnly(title: "Forms"), [a("home", "Open", "list.bullet.rectangle.fill", "/forms/u/0/")]),
|
|
|
+ v("forms_medium", "Forms Shortcuts", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/forms/u/0/"),
|
|
|
+ a("new", "New form", "plus", "https://docs.google.com/forms/create"),
|
|
|
+ a("contacts", "Contacts", "person.crop.circle", "/forms/u/0/contacts"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/forms/u/0/search"),
|
|
|
+ ]),
|
|
|
+ v("forms_large", "Forms Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/forms/u/0/"),
|
|
|
+ a("new", "New form", "plus", "https://docs.google.com/forms/create"),
|
|
|
+ a("starred", "Starred", "star", "/forms/u/0/starred"),
|
|
|
+ a("shared", "Shared", "person.2", "/forms/u/0/shared-with-me"),
|
|
|
+ a("trash", "Trash", "trash", "/forms/u/0/trash"),
|
|
|
+ a("contacts", "Contacts", "person.crop.circle", "/forms/u/0/contacts"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/forms/u/0/search"),
|
|
|
+ a("settings", "Settings", "gearshape", "/forms/u/0/settings"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .calendar:
|
|
|
return [
|
|
|
v("calendar_small", "Today", .small, false, .actionsRow, [
|
|
|
@@ -97,22 +185,32 @@ enum WidgetTemplates {
|
|
|
]),
|
|
|
v("calendar_medium", "Schedule", .medium, true, .actionsGrid(columns: 2), [
|
|
|
a("today", "Today", "calendar", "/calendar/u/0/r"),
|
|
|
- a("week", "Week", "calendar.badge.clock", "/calendar/u/0/r"),
|
|
|
+ a("week", "Week", "calendar.badge.clock", "/calendar/u/0/r/week"),
|
|
|
+ a("create", "New Event", "plus.circle", "/calendar/u/0/r/eventedit"),
|
|
|
+ a("tasks", "Tasks", "checkmark.square", "https://tasks.google.com/"),
|
|
|
+ ]),
|
|
|
+ v("calendar_large", "Calendar Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("today", "Today", "calendar", "/calendar/u/0/r"),
|
|
|
+ a("week", "Week", "calendar.badge.clock", "/calendar/u/0/r/week"),
|
|
|
+ a("month", "Month", "calendar", "/calendar/u/0/r/month"),
|
|
|
a("create", "New Event", "plus.circle", "/calendar/u/0/r/eventedit"),
|
|
|
- a("tasks", "Tasks", "checkmark.square", "/calendar/u/0/r"),
|
|
|
+ a("tasks", "Tasks", "checkmark.square", "https://tasks.google.com/"),
|
|
|
+ a("settings", "Settings", "gearshape", "/calendar/u/0/r/settings"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/calendar/u/0/r/search"),
|
|
|
+ a("print", "Print", "printer", "/calendar/u/0/r/print"),
|
|
|
]),
|
|
|
]
|
|
|
case .maps:
|
|
|
return [
|
|
|
- v("maps_small", "Places", .small, false, .actionsRow, [
|
|
|
- a("search", "Search", "magnifyingglass", "/"),
|
|
|
- a("nearby", "Nearby", "mappin.and.ellipse", "/"),
|
|
|
+ v("maps_small", "Maps", .small, false, .actionsRow, [
|
|
|
+ a("search", "Search", "magnifyingglass", "https://www.google.com/maps"),
|
|
|
+ a("directions", "Directions", "arrow.triangle.turn.up.right.diamond", "https://www.google.com/maps/dir/"),
|
|
|
]),
|
|
|
- v("maps_medium", "Routing", .medium, true, .actionsGrid(columns: 2), [
|
|
|
- a("search", "Search", "magnifyingglass", "/"),
|
|
|
- a("directions", "Directions", "arrow.triangle.turn.up.right.diamond", "/"),
|
|
|
- a("saved", "Saved", "bookmark", "/"),
|
|
|
- a("traffic", "Traffic", "car", "/"),
|
|
|
+ v("maps_medium", "Places & routes", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("search", "Search", "magnifyingglass", "https://www.google.com/maps"),
|
|
|
+ a("directions", "Directions", "arrow.triangle.turn.up.right.diamond", "https://www.google.com/maps/dir/"),
|
|
|
+ a("saved", "Saved", "bookmark", "https://www.google.com/maps/saved"),
|
|
|
+ a("traffic", "Traffic", "car", "https://www.google.com/maps/@?layer=traffic"),
|
|
|
]),
|
|
|
]
|
|
|
case .youtube:
|
|
|
@@ -122,6 +220,12 @@ enum WidgetTemplates {
|
|
|
a("shorts", "Shorts", "bolt", "/shorts"),
|
|
|
a("subs", "Subs", "play.rectangle", "/feed/subscriptions"),
|
|
|
]),
|
|
|
+ v("youtube_medium", "Browse", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Home", "house", "/"),
|
|
|
+ a("trending", "Trending", "flame", "/feed/trending"),
|
|
|
+ a("shorts", "Shorts", "bolt", "/shorts"),
|
|
|
+ a("subs", "Subscriptions", "play.rectangle", "/feed/subscriptions"),
|
|
|
+ ]),
|
|
|
v("youtube_large", "Library", .large, true, .actionsGrid(columns: 2), [
|
|
|
a("home", "Home", "house", "/"),
|
|
|
a("shorts", "Shorts", "play.square", "/shorts"),
|
|
|
@@ -132,53 +236,297 @@ enum WidgetTemplates {
|
|
|
]),
|
|
|
]
|
|
|
case .translate:
|
|
|
- return utilityVariants(prefix: "translate", appName: "Translate", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("translate_small", "Translate", .small, false, .actionsRow, [
|
|
|
+ a("open", "Translator", "character.bubble.fill", "/"),
|
|
|
+ a("history", "History", "clock", "/m/"),
|
|
|
+ a("saved", "Phrasebook", "bookmark", "/m/"),
|
|
|
+ ]),
|
|
|
+ v("translate_medium", "Translate Tools", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("open", "Web translator", "globe", "/"),
|
|
|
+ a("docs", "Documents", "doc.text", "https://translate.google.com/?tr=f&hl=en&tab=wT"),
|
|
|
+ a("conversation", "Conversation", "bubble.left.and.bubble.right", "/m/"),
|
|
|
+ a("history", "History", "clock", "/m/"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .search:
|
|
|
- return utilityVariants(prefix: "search", appName: "Search", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("search_small", "Search", .small, false, .actionsRow, [
|
|
|
+ a("web", "Web", "globe", "/"),
|
|
|
+ a("images", "Images", "photo", "https://www.google.com/imghp"),
|
|
|
+ a("maps", "Maps", "map", "https://maps.google.com/maps"),
|
|
|
+ ]),
|
|
|
+ v("search_medium", "Google Shortcuts", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("web", "Web", "globe", "/"),
|
|
|
+ a("images", "Images", "photo", "https://www.google.com/imghp"),
|
|
|
+ a("shopping", "Shopping", "bag", "https://www.google.com/search?tbm=shop"),
|
|
|
+ a("maps", "Maps", "map", "https://maps.google.com/maps"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .earth:
|
|
|
- return utilityVariants(prefix: "earth", appName: "Earth", basePath: "/web/")
|
|
|
+ return [
|
|
|
+ v("earth_small", "Earth", .small, false, .actionsRow, [
|
|
|
+ a("open", "Open", "globe.americas.fill", "/web/"),
|
|
|
+ a("projects", "Projects", "folder", "/web/projects/"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/web/search"),
|
|
|
+ ]),
|
|
|
+ v("earth_medium", "Earth Explorer", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("open", "Open", "globe.americas.fill", "/web/"),
|
|
|
+ a("voyager", "Voyager", "sailboat", "/web/data/"),
|
|
|
+ a("projects", "Projects", "folder", "/web/projects/"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/web/search"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .shopping:
|
|
|
- return mediaVariants(prefix: "shopping", appName: "Shopping", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("shopping_small", "Shopping", .small, false, .iconOnly(title: "Shopping"), [a("open", "Open", "bag.fill", "/")]),
|
|
|
+ v("shopping_medium", "Shopping Browse", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Home", "house", "/"),
|
|
|
+ a("deals", "Deals", "tag", "/"),
|
|
|
+ a("saved", "Saved", "bookmark", "/"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .keep:
|
|
|
- return utilityVariants(prefix: "keep", appName: "Keep", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("keep_small", "Keep", .small, false, .actionsRow, [
|
|
|
+ a("notes", "Notes", "note.text", "/"),
|
|
|
+ a("reminders", "Reminders", "bell", "/#reminders"),
|
|
|
+ a("archive", "Archive", "archivebox", "/#archive"),
|
|
|
+ ]),
|
|
|
+ v("keep_medium", "Keep Hub", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("notes", "Notes", "note.text", "/"),
|
|
|
+ a("reminders", "Reminders", "bell", "/#reminders"),
|
|
|
+ a("labels", "Labels", "tag", "/#label"),
|
|
|
+ a("archive", "Archive", "archivebox", "/#archive"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .travel:
|
|
|
- return mediaVariants(prefix: "travel", appName: "Travel", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("travel_small", "Travel", .small, false, .iconOnly(title: "Travel"), [a("trips", "Trips", "airplane", "/travel")]),
|
|
|
+ v("travel_medium", "Trip Planner", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("trips", "Trips", "airplane", "/travel"),
|
|
|
+ a("explore", "Explore", "globe", "/travel/explore"),
|
|
|
+ a("flights", "Flights", "airplane.departure", "/flights"),
|
|
|
+ a("hotels", "Hotels", "bed.double", "/hotels"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .meet:
|
|
|
- return communicationVariants(prefix: "meet", appName: "Meet", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("meet_small", "Meet", .small, false, .actionsRow, [
|
|
|
+ a("join", "Join", "video.badge.plus", "/"),
|
|
|
+ a("new", "New", "plus.circle", "/new"),
|
|
|
+ a("landing", "Home", "house", "/landing"),
|
|
|
+ ]),
|
|
|
+ v("meet_large", "Meet Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("new", "New meeting", "video.badge.plus", "/new"),
|
|
|
+ a("join", "Join", "person.wave.2", "/"),
|
|
|
+ a("landing", "Home", "house", "/landing"),
|
|
|
+ a("schedule", "Schedule", "calendar", "https://calendar.google.com/calendar/u/0/r/eventedit"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .contacts:
|
|
|
- return utilityVariants(prefix: "contacts", appName: "Contacts", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("contacts_small", "Contacts", .small, false, .actionsRow, [
|
|
|
+ a("contacts", "Contacts", "person.crop.circle", "/"),
|
|
|
+ a("duplicates", "Duplicates", "person.2", "/duplicates"),
|
|
|
+ a("labels", "Labels", "tag", "/"),
|
|
|
+ ]),
|
|
|
+ v("contacts_medium", "Contacts Hub", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("contacts", "All", "person.crop.circle", "/"),
|
|
|
+ a("frequent", "Frequent", "clock", "/"),
|
|
|
+ a("duplicates", "Duplicates", "person.2", "/duplicates"),
|
|
|
+ a("trash", "Trash", "trash", "/trash"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .blogger:
|
|
|
- return mediaVariants(prefix: "blogger", appName: "Blogger", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("blogger_small", "Blogger", .small, false, .iconOnly(title: "Blogger"), [a("home", "Open", "text.book.closed.fill", "/")]),
|
|
|
+ v("blogger_medium", "Blogger Tools", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Reading list", "list.bullet", "/"),
|
|
|
+ a("create", "New post", "square.and.pencil", "/"),
|
|
|
+ a("reading", "Reading list", "book", "/reading-list"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .play:
|
|
|
- return mediaVariants(prefix: "play", appName: "Play", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("play_small", "Play", .small, false, .iconOnly(title: "Play"), [a("store", "Store", "play.circle.fill", "/store/apps")]),
|
|
|
+ v("play_medium", "Play Store", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("apps", "Apps", "app.badge", "/store/apps"),
|
|
|
+ a("games", "Games", "gamecontroller", "/store/games"),
|
|
|
+ a("movies", "Movies", "film", "/store/movies"),
|
|
|
+ a("books", "Books", "book", "/store/books"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .news:
|
|
|
- return mediaVariants(prefix: "news", appName: "News", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("news_small", "News", .small, false, .iconOnly(title: "News"), [a("home", "Headlines", "newspaper.fill", "/home")]),
|
|
|
+ v("news_medium", "News Feeds", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("foryou", "For you", "person.crop.circle", "/foryou"),
|
|
|
+ a("headlines", "Headlines", "newspaper", "/topstories"),
|
|
|
+ a("topics", "Topics", "square.grid.2x2", "/topics"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/search"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .chat:
|
|
|
- return communicationVariants(prefix: "chat", appName: "Chat", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("chat_small", "Chat", .small, false, .actionsRow, [
|
|
|
+ a("home", "Home", "bubble.left.and.bubble.right.fill", "/u/0/"),
|
|
|
+ a("spaces", "Spaces", "square.grid.3x3.fill", "/u/0/spaces"),
|
|
|
+ a("meet", "Meet", "video", "https://meet.google.com/"),
|
|
|
+ ]),
|
|
|
+ v("chat_large", "Chat Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Home", "house", "/u/0/"),
|
|
|
+ a("spaces", "Spaces", "square.grid.3x3.fill", "/u/0/spaces"),
|
|
|
+ a("browse", "Browse", "square.grid.2x2", "/u/0/browse"),
|
|
|
+ a("meet", "Meet", "video", "https://meet.google.com/"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .finance:
|
|
|
- return mediaVariants(prefix: "finance", appName: "Finance", basePath: "/finance")
|
|
|
+ return [
|
|
|
+ v("finance_small", "Finance", .small, false, .actionsRow, [
|
|
|
+ a("home", "Markets", "chart.line.uptrend.xyaxis", "/finance"),
|
|
|
+ a("markets", "Markets", "chart.bar", "/finance/markets"),
|
|
|
+ a("portfolio", "Portfolio", "briefcase", "/finance/portfolio"),
|
|
|
+ ]),
|
|
|
+ v("finance_medium", "Finance Hub", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Home", "house", "/finance"),
|
|
|
+ a("markets", "Markets", "chart.bar", "/finance/markets"),
|
|
|
+ a("portfolio", "Portfolio", "briefcase", "/finance/portfolio"),
|
|
|
+ a("news", "News", "newspaper", "/finance/news"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .jamboard:
|
|
|
- return communicationVariants(prefix: "jamboard", appName: "Jamboard", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("jamboard_small", "Jamboard", .small, false, .actionsRow, [
|
|
|
+ a("open", "Boards", "paintbrush.fill", "/"),
|
|
|
+ a("create", "New jam", "plus", "/"),
|
|
|
+ a("shared", "Shared", "person.2", "/"),
|
|
|
+ ]),
|
|
|
+ v("jamboard_large", "Jamboard", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("open", "Home", "house", "/"),
|
|
|
+ a("create", "New jam", "plus", "/"),
|
|
|
+ a("shared", "Shared with me", "person.2", "/"),
|
|
|
+ a("trash", "Trash", "trash", "/"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .classroom:
|
|
|
- return communicationVariants(prefix: "classroom", appName: "Classroom", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("classroom_small", "Classroom", .small, false, .actionsRow, [
|
|
|
+ a("home", "Classes", "graduationcap.fill", "/u/0/h/"),
|
|
|
+ a("calendar", "Calendar", "calendar", "/u/0/calendar"),
|
|
|
+ a("todo", "To-do", "checklist", "/u/0/notifications"),
|
|
|
+ ]),
|
|
|
+ v("classroom_large", "Classroom Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Home", "house", "/u/0/h/"),
|
|
|
+ a("calendar", "Calendar", "calendar", "/u/0/calendar"),
|
|
|
+ a("archive", "Archive", "archivebox", "/u/0/archived"),
|
|
|
+ a("settings", "Settings", "gearshape", "/u/0/settings"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .artsCulture:
|
|
|
- return mediaVariants(prefix: "arts", appName: "Arts & Culture", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("arts_small", "Arts & Culture", .small, false, .iconOnly(title: "Arts"), [a("home", "Explore", "building.columns.fill", "/")]),
|
|
|
+ v("arts_medium", "Arts Browse", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Home", "house", "/"),
|
|
|
+ a("explore", "Explore", "globe", "/explore"),
|
|
|
+ a("nearby", "Near you", "mappin.and.ellipse", "/nearby"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/search"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .voice:
|
|
|
- return communicationVariants(prefix: "voice", appName: "Voice", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("voice_small", "Voice", .small, false, .actionsRow, [
|
|
|
+ a("messages", "Messages", "bubble.left", "/messages"),
|
|
|
+ a("calls", "Calls", "phone", "/calls"),
|
|
|
+ a("voicemail", "Voicemail", "recordingtape", "/voicemail"),
|
|
|
+ ]),
|
|
|
+ v("voice_large", "Voice Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("messages", "Messages", "bubble.left", "/messages"),
|
|
|
+ a("calls", "Calls", "phone", "/calls"),
|
|
|
+ a("voicemail", "Voicemail", "recordingtape", "/voicemail"),
|
|
|
+ a("settings", "Settings", "gearshape", "/settings"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .chromeWebStore:
|
|
|
- return mediaVariants(prefix: "webstore", appName: "Web Store", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("webstore_small", "Web Store", .small, false, .iconOnly(title: "Web Store"), [a("home", "Store", "bag.fill", "/webstore")]),
|
|
|
+ v("webstore_medium", "Chrome Web Store", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("extensions", "Extensions", "puzzlepiece.extension", "/webstore/category/extensions"),
|
|
|
+ a("themes", "Themes", "paintpalette", "/webstore/category/themes"),
|
|
|
+ a("home", "Home", "house", "/webstore"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/webstore/search"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .fi:
|
|
|
- return utilityVariants(prefix: "fi", appName: "Fi", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("fi_small", "Fi", .small, false, .actionsRow, [
|
|
|
+ a("home", "Account", "antenna.radiowaves.left.and.right", "/"),
|
|
|
+ a("billing", "Billing", "creditcard", "/billing"),
|
|
|
+ a("coverage", "Coverage", "map", "/coverage"),
|
|
|
+ ]),
|
|
|
+ v("fi_medium", "Google Fi", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Home", "house", "/"),
|
|
|
+ a("billing", "Billing", "creditcard", "/billing"),
|
|
|
+ a("coverage", "Coverage", "map", "/coverage"),
|
|
|
+ a("support", "Support", "questionmark.circle", "/support"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .ads:
|
|
|
- return utilityVariants(prefix: "ads", appName: "Ads", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("ads_small", "Ads", .small, false, .actionsRow, [
|
|
|
+ a("home", "Overview", "megaphone.fill", "/aw/"),
|
|
|
+ a("campaigns", "Campaigns", "chart.bar", "/aw/campaigns"),
|
|
|
+ a("reports", "Reports", "doc.text", "/aw/reports"),
|
|
|
+ ]),
|
|
|
+ v("ads_medium", "Google Ads", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("home", "Home", "house", "/aw/"),
|
|
|
+ a("campaigns", "Campaigns", "chart.bar", "/aw/campaigns"),
|
|
|
+ a("tools", "Tools", "wrench", "/aw/tools"),
|
|
|
+ a("billing", "Billing", "creditcard", "/aw/billing"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .remoteDesktop:
|
|
|
- return utilityVariants(prefix: "remote", appName: "Remote Desktop", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("remote_small", "Remote", .small, false, .actionsRow, [
|
|
|
+ a("access", "Remote access", "desktopcomputer", "/access"),
|
|
|
+ a("support", "Support", "person.crop.circle", "/support"),
|
|
|
+ a("downloads", "Downloads", "arrow.down.circle", "/"),
|
|
|
+ ]),
|
|
|
+ v("remote_large", "Remote Desktop", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("access", "Remote access", "desktopcomputer", "/access"),
|
|
|
+ a("support", "Support", "person.crop.circle", "/support"),
|
|
|
+ a("downloads", "Downloads", "arrow.down.circle", "/"),
|
|
|
+ a("help", "Help", "questionmark.circle", "/support"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .gemini:
|
|
|
- return communicationVariants(prefix: "gemini", appName: "Gemini", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("gemini_small", "Gemini", .small, false, .actionsRow, [
|
|
|
+ a("app", "Gemini", "sparkles", "/app"),
|
|
|
+ a("home", "Home", "house", "/"),
|
|
|
+ a("extensions", "Extensions", "puzzlepiece", "/extensions"),
|
|
|
+ ]),
|
|
|
+ v("gemini_large", "Gemini Hub", .large, true, .actionsGrid(columns: 2), [
|
|
|
+ a("app", "Chat", "sparkles", "/app"),
|
|
|
+ a("home", "Home", "house", "/"),
|
|
|
+ a("extensions", "Extensions", "puzzlepiece", "/extensions"),
|
|
|
+ a("help", "Help", "questionmark.circle", "/help"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .books:
|
|
|
- return mediaVariants(prefix: "books", appName: "Books", basePath: "/")
|
|
|
+ return [
|
|
|
+ v("books_small", "Books", .small, false, .iconOnly(title: "Books"), [a("home", "Library", "book.fill", "/ebooks")]),
|
|
|
+ v("books_medium", "Google Books", .medium, true, .actionsGrid(columns: 2), [
|
|
|
+ a("library", "My books", "books.vertical", "/ebooks/library"),
|
|
|
+ a("shop", "Shop", "cart", "/ebooks"),
|
|
|
+ a("audiobooks", "Audiobooks", "headphones", "/audiobooks"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/ebooks/search"),
|
|
|
+ ]),
|
|
|
+ ]
|
|
|
case .unknown:
|
|
|
- return utilityVariants(prefix: "generic", appName: app.name, basePath: "/")
|
|
|
+ return genericUtilityVariants(prefix: "generic", appName: app.name)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -199,152 +547,7 @@ enum WidgetTemplates {
|
|
|
}
|
|
|
|
|
|
private extension WidgetTemplates {
|
|
|
- enum AppWidgetProfile {
|
|
|
- case photos, gmail, drive, docs, sheets, slides, forms
|
|
|
- case calendar, maps, youtube, translate, search, earth, shopping
|
|
|
- case keep, travel, meet, contacts, blogger, play, news, chat, finance
|
|
|
- case jamboard, classroom, artsCulture, voice, chromeWebStore, fi, ads
|
|
|
- case remoteDesktop, gemini, books
|
|
|
- case unknown
|
|
|
- }
|
|
|
-
|
|
|
- static func appProfile(for app: LauncherApp) -> AppWidgetProfile {
|
|
|
- let host = app.webURL?.host?.lowercased() ?? ""
|
|
|
- let name = app.name.lowercased()
|
|
|
- if host.contains("photos.google.com") || name.contains("photos") { return .photos }
|
|
|
- if host.contains("mail.google.com") || name == "gmail" { return .gmail }
|
|
|
- if host.contains("drive.google.com") { return .drive }
|
|
|
- if host.contains("docs.google.com") { return .docs }
|
|
|
- if host.contains("sheets.google.com") { return .sheets }
|
|
|
- if host.contains("slides.google.com") { return .slides }
|
|
|
- if host.contains("forms.google.com") { return .forms }
|
|
|
- if host.contains("calendar.google.com") { return .calendar }
|
|
|
- if host.contains("maps.google.com") { return .maps }
|
|
|
- if host.contains("youtube.com") { return .youtube }
|
|
|
- if host.contains("translate.google.com") { return .translate }
|
|
|
- if host == "www.google.com" || host == "google.com" { return .search }
|
|
|
- if host.contains("earth.google.com") { return .earth }
|
|
|
- if host.contains("shopping.google.com") { return .shopping }
|
|
|
- if host.contains("keep.google.com") { return .keep }
|
|
|
- if host.contains("travel.google.com") { return .travel }
|
|
|
- if host.contains("meet.google.com") { return .meet }
|
|
|
- if host.contains("contacts.google.com") { return .contacts }
|
|
|
- if host.contains("blogger.com") { return .blogger }
|
|
|
- if host.contains("play.google.com") { return .play }
|
|
|
- if host.contains("news.google.com") { return .news }
|
|
|
- if host.contains("chat.google.com") { return .chat }
|
|
|
- if host.contains("/finance") || name.contains("finance") { return .finance }
|
|
|
- if host.contains("jamboard.google.com") { return .jamboard }
|
|
|
- if host.contains("classroom.google.com") { return .classroom }
|
|
|
- if host.contains("artsandculture.google.com") { return .artsCulture }
|
|
|
- if host.contains("voice.google.com") { return .voice }
|
|
|
- if host.contains("chrome.google.com") { return .chromeWebStore }
|
|
|
- if host.contains("fi.google.com") { return .fi }
|
|
|
- if host.contains("ads.google.com") { return .ads }
|
|
|
- if host.contains("remotedesktop.google.com") { return .remoteDesktop }
|
|
|
- if host.contains("gemini.google.com") { return .gemini }
|
|
|
- if host.contains("books.google.com") { return .books }
|
|
|
- return .unknown
|
|
|
- }
|
|
|
-
|
|
|
- static func contentWorkspaceVariants(prefix: String, appName: String, rootPath: String, searchPath: String) -> [WidgetVariant] {
|
|
|
- [
|
|
|
- WidgetVariant(
|
|
|
- id: "\(prefix)_small",
|
|
|
- title: appName,
|
|
|
- size: .small,
|
|
|
- showHeader: false,
|
|
|
- layoutMode: .iconOnly(title: appName),
|
|
|
- actions: [a("open", "Open", "arrow.up.right", rootPath)]
|
|
|
- ),
|
|
|
- WidgetVariant(
|
|
|
- id: "\(prefix)_medium",
|
|
|
- title: "Recent",
|
|
|
- size: .medium,
|
|
|
- showHeader: true,
|
|
|
- layoutMode: .actionsGrid(columns: 2),
|
|
|
- actions: [
|
|
|
- a("open", "Open", "arrow.up.right", rootPath),
|
|
|
- a("search", "Search", "magnifyingglass", searchPath),
|
|
|
- a("favorites", "Favorites", "star", rootPath),
|
|
|
- a("shared", "Shared", "person.2", rootPath),
|
|
|
- ]
|
|
|
- ),
|
|
|
- WidgetVariant(
|
|
|
- id: "\(prefix)_large",
|
|
|
- title: "Workspace",
|
|
|
- size: .large,
|
|
|
- showHeader: true,
|
|
|
- layoutMode: .actionsGrid(columns: 2),
|
|
|
- actions: [
|
|
|
- a("open", "Open", "arrow.up.right", rootPath),
|
|
|
- a("search", "Search", "magnifyingglass", searchPath),
|
|
|
- a("new", "New", "plus", rootPath),
|
|
|
- a("recent", "Recent", "clock.arrow.circlepath", rootPath),
|
|
|
- a("starred", "Starred", "star", rootPath),
|
|
|
- a("shared", "Shared", "person.2", rootPath),
|
|
|
- ]
|
|
|
- ),
|
|
|
- ]
|
|
|
- }
|
|
|
-
|
|
|
- static func communicationVariants(prefix: String, appName: String, basePath: String) -> [WidgetVariant] {
|
|
|
- [
|
|
|
- WidgetVariant(
|
|
|
- id: "\(prefix)_small",
|
|
|
- title: "Quick",
|
|
|
- size: .small,
|
|
|
- showHeader: false,
|
|
|
- layoutMode: .actionsRow,
|
|
|
- actions: [
|
|
|
- a("open", "Open", "arrow.up.right", basePath),
|
|
|
- a("recent", "Recent", "clock", basePath),
|
|
|
- a("contacts", "Contacts", "person.2", basePath),
|
|
|
- ]
|
|
|
- ),
|
|
|
- WidgetVariant(
|
|
|
- id: "\(prefix)_large",
|
|
|
- title: appName,
|
|
|
- size: .large,
|
|
|
- showHeader: true,
|
|
|
- layoutMode: .actionsGrid(columns: 2),
|
|
|
- actions: [
|
|
|
- a("open", "Open", "arrow.up.right", basePath),
|
|
|
- a("messages", "Messages", "bubble.left.and.bubble.right", basePath),
|
|
|
- a("meetings", "Meetings", "video", basePath),
|
|
|
- a("contacts", "Contacts", "person.2", basePath),
|
|
|
- ]
|
|
|
- ),
|
|
|
- ]
|
|
|
- }
|
|
|
-
|
|
|
- static func mediaVariants(prefix: String, appName: String, basePath: String) -> [WidgetVariant] {
|
|
|
- [
|
|
|
- WidgetVariant(
|
|
|
- id: "\(prefix)_small",
|
|
|
- title: appName,
|
|
|
- size: .small,
|
|
|
- showHeader: false,
|
|
|
- layoutMode: .iconOnly(title: appName),
|
|
|
- actions: [a("open", "Open", "arrow.up.right", basePath)]
|
|
|
- ),
|
|
|
- WidgetVariant(
|
|
|
- id: "\(prefix)_medium",
|
|
|
- title: "Browse",
|
|
|
- size: .medium,
|
|
|
- showHeader: true,
|
|
|
- layoutMode: .actionsGrid(columns: 2),
|
|
|
- actions: [
|
|
|
- a("open", "Open", "arrow.up.right", basePath),
|
|
|
- a("trending", "Trending", "chart.line.uptrend.xyaxis", basePath),
|
|
|
- a("saved", "Saved", "bookmark", basePath),
|
|
|
- a("search", "Search", "magnifyingglass", basePath),
|
|
|
- ]
|
|
|
- ),
|
|
|
- ]
|
|
|
- }
|
|
|
-
|
|
|
- static func utilityVariants(prefix: String, appName: String, basePath: String) -> [WidgetVariant] {
|
|
|
+ static func genericUtilityVariants(prefix: String, appName: String) -> [WidgetVariant] {
|
|
|
[
|
|
|
WidgetVariant(
|
|
|
id: "\(prefix)_small",
|
|
|
@@ -353,9 +556,9 @@ private extension WidgetTemplates {
|
|
|
showHeader: false,
|
|
|
layoutMode: .actionsRow,
|
|
|
actions: [
|
|
|
- a("open", "Open", "arrow.up.right", basePath),
|
|
|
- a("search", "Search", "magnifyingglass", basePath),
|
|
|
- a("favorites", "Favorites", "star", basePath),
|
|
|
+ a("open", "Open", "arrow.up.right", "/"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/"),
|
|
|
+ a("favorites", "Favorites", "star", "/"),
|
|
|
]
|
|
|
),
|
|
|
WidgetVariant(
|
|
|
@@ -365,10 +568,10 @@ private extension WidgetTemplates {
|
|
|
showHeader: true,
|
|
|
layoutMode: .actionsGrid(columns: 2),
|
|
|
actions: [
|
|
|
- a("open", "Open", "arrow.up.right", basePath),
|
|
|
- a("search", "Search", "magnifyingglass", basePath),
|
|
|
- a("favorites", "Favorites", "star", basePath),
|
|
|
- a("recent", "Recent", "clock.arrow.circlepath", basePath),
|
|
|
+ a("open", "Open", "arrow.up.right", "/"),
|
|
|
+ a("search", "Search", "magnifyingglass", "/"),
|
|
|
+ a("favorites", "Favorites", "star", "/"),
|
|
|
+ a("recent", "Recent", "clock.arrow.circlepath", "/"),
|
|
|
]
|
|
|
),
|
|
|
]
|
|
|
@@ -378,4 +581,3 @@ private extension WidgetTemplates {
|
|
|
WidgetAction(id: id, title: title, systemImage: image, urlPath: path)
|
|
|
}
|
|
|
}
|
|
|
-
|