|
@@ -1,8 +1,7 @@
|
|
|
import AppKit
|
|
import AppKit
|
|
|
import SwiftUI
|
|
import SwiftUI
|
|
|
-import WebKit
|
|
|
|
|
|
|
|
|
|
-/// Tiered Google Drive desktop widget: recent files, starred preview, or full embedded Drive.
|
|
|
|
|
|
|
+/// Tiered Google Drive desktop widget: recent files, starred preview, or a large shortcut hub (opens Drive in the app browser).
|
|
|
struct DriveDesktopWidgetView: View {
|
|
struct DriveDesktopWidgetView: View {
|
|
|
let app: LauncherApp
|
|
let app: LauncherApp
|
|
|
let mode: DriveWidgetMode
|
|
let mode: DriveWidgetMode
|
|
@@ -247,29 +246,16 @@ struct DriveDesktopWidgetView: View {
|
|
|
.allowsHitTesting(!isPreview)
|
|
.allowsHitTesting(!isPreview)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // MARK: - Large (interactive)
|
|
|
|
|
|
|
+ // MARK: - Large (shortcut hub — opens Drive in app browser; no embedded web app)
|
|
|
|
|
|
|
|
@State private var searchText = ""
|
|
@State private var searchText = ""
|
|
|
- @State private var webURL: URL
|
|
|
|
|
-
|
|
|
|
|
- init(app: LauncherApp, mode: DriveWidgetMode, isPreview: Bool = false) {
|
|
|
|
|
- self.app = app
|
|
|
|
|
- self.mode = mode
|
|
|
|
|
- self.isPreview = isPreview
|
|
|
|
|
- let base = app.webURL ?? URL(string: "https://drive.google.com")!
|
|
|
|
|
- _webURL = State(initialValue: Self.defaultDriveURL(base: base))
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private static func defaultDriveURL(base: URL) -> URL {
|
|
|
|
|
- WidgetDeepLinkURL.resolved(base: base, actionPath: "/drive/home", accountSlot: 0)
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
private var interactiveBody: some View {
|
|
private var interactiveBody: some View {
|
|
|
Group {
|
|
Group {
|
|
|
if isPreview {
|
|
if isPreview {
|
|
|
interactivePreviewChrome
|
|
interactivePreviewChrome
|
|
|
} else {
|
|
} else {
|
|
|
- interactiveLiveChrome
|
|
|
|
|
|
|
+ interactiveHubChrome
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -289,7 +275,7 @@ struct DriveDesktopWidgetView: View {
|
|
|
Text("Google Drive")
|
|
Text("Google Drive")
|
|
|
.font(.system(size: 15, weight: .bold))
|
|
.font(.system(size: 15, weight: .bold))
|
|
|
.foregroundStyle(.white.opacity(0.92))
|
|
.foregroundStyle(.white.opacity(0.92))
|
|
|
- Text("Search, folders, previews, and create options load on your desktop.")
|
|
|
|
|
|
|
+ Text("Search, folders, and create shortcuts open in the app browser — no embedded Drive page.")
|
|
|
.font(.system(size: 11, weight: .medium))
|
|
.font(.system(size: 11, weight: .medium))
|
|
|
.foregroundStyle(.white.opacity(0.65))
|
|
.foregroundStyle(.white.opacity(0.65))
|
|
|
.multilineTextAlignment(.center)
|
|
.multilineTextAlignment(.center)
|
|
@@ -299,34 +285,43 @@ struct DriveDesktopWidgetView: View {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private var interactiveLiveChrome: some View {
|
|
|
|
|
- ZStack {
|
|
|
|
|
- RoundedRectangle(cornerRadius: 22, style: .continuous)
|
|
|
|
|
- .fill(Color.black.opacity(0.32))
|
|
|
|
|
-
|
|
|
|
|
- VStack(spacing: 0) {
|
|
|
|
|
- VStack(spacing: 8) {
|
|
|
|
|
|
|
+ private var interactiveHubChrome: some View {
|
|
|
|
|
+ ZStack(alignment: .topLeading) {
|
|
|
|
|
+ driveGradientBackground
|
|
|
|
|
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
|
|
|
+ ScrollView {
|
|
|
|
|
+ VStack(alignment: .leading, spacing: 14) {
|
|
|
interactiveHeader
|
|
interactiveHeader
|
|
|
interactiveSearchBar
|
|
interactiveSearchBar
|
|
|
|
|
+
|
|
|
|
|
+ hubSectionTitle("Folders")
|
|
|
folderChipsRow
|
|
folderChipsRow
|
|
|
- createAndUploadRow
|
|
|
|
|
- }
|
|
|
|
|
- .padding(.horizontal, 6)
|
|
|
|
|
- .padding(.vertical, 8)
|
|
|
|
|
- .background(
|
|
|
|
|
- RoundedRectangle(cornerRadius: 16, style: .continuous)
|
|
|
|
|
- .fill(Color(red: 0.06, green: 0.1, blue: 0.09))
|
|
|
|
|
- )
|
|
|
|
|
- .zIndex(20)
|
|
|
|
|
|
|
|
|
|
- DriveWebWidgetView(url: $webURL)
|
|
|
|
|
- .frame(minHeight: 280)
|
|
|
|
|
- .frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
|
|
|
- .clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
|
|
|
|
|
- .zIndex(0)
|
|
|
|
|
|
|
+ hubSectionTitle("Quick find")
|
|
|
|
|
+ quickFindChipsRow
|
|
|
|
|
+
|
|
|
|
|
+ hubSectionTitle("Create")
|
|
|
|
|
+ createExpandedGrid
|
|
|
|
|
+
|
|
|
|
|
+ hubSectionTitle("More")
|
|
|
|
|
+ moreToolsRow
|
|
|
|
|
+
|
|
|
|
|
+ drivePrimaryButton(title: "Open full Google Drive", systemImage: "safari") {
|
|
|
|
|
+ openDrivePath("/drive/home")
|
|
|
|
|
+ }
|
|
|
|
|
+ .padding(.top, 4)
|
|
|
|
|
+ }
|
|
|
|
|
+ .padding(14)
|
|
|
}
|
|
}
|
|
|
- .padding(10)
|
|
|
|
|
|
|
+ .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
|
|
}
|
|
}
|
|
|
|
|
+ .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private func hubSectionTitle(_ text: String) -> some View {
|
|
|
|
|
+ Text(text)
|
|
|
|
|
+ .font(.system(size: 11, weight: .bold))
|
|
|
|
|
+ .foregroundStyle(.white.opacity(0.58))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private var interactiveHeader: some View {
|
|
private var interactiveHeader: some View {
|
|
@@ -377,80 +372,116 @@ struct DriveDesktopWidgetView: View {
|
|
|
private var folderChipsRow: some View {
|
|
private var folderChipsRow: some View {
|
|
|
ScrollView(.horizontal, showsIndicators: false) {
|
|
ScrollView(.horizontal, showsIndicators: false) {
|
|
|
HStack(spacing: 8) {
|
|
HStack(spacing: 8) {
|
|
|
|
|
+ driveChip("Home", path: "/drive/home")
|
|
|
driveChip("My Drive", path: "/drive/my-drive")
|
|
driveChip("My Drive", path: "/drive/my-drive")
|
|
|
driveChip("Recent", path: "/drive/recent")
|
|
driveChip("Recent", path: "/drive/recent")
|
|
|
driveChip("Starred", path: "/drive/starred")
|
|
driveChip("Starred", path: "/drive/starred")
|
|
|
driveChip("Shared", path: "/drive/shared-with-me")
|
|
driveChip("Shared", path: "/drive/shared-with-me")
|
|
|
driveChip("Shared drives", path: "/drive/shared-drives")
|
|
driveChip("Shared drives", path: "/drive/shared-drives")
|
|
|
driveChip("Computers", path: "/drive/computers")
|
|
driveChip("Computers", path: "/drive/computers")
|
|
|
|
|
+ driveChip("Offline", path: "/drive/offline")
|
|
|
driveChip("Trash", path: "/drive/trash")
|
|
driveChip("Trash", path: "/drive/trash")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private var createAndUploadRow: some View {
|
|
|
|
|
- VStack(alignment: .leading, spacing: 6) {
|
|
|
|
|
- Text("Create")
|
|
|
|
|
- .font(.system(size: 10, weight: .bold))
|
|
|
|
|
- .foregroundStyle(.white.opacity(0.55))
|
|
|
|
|
- ScrollView(.horizontal, showsIndicators: false) {
|
|
|
|
|
- HStack(spacing: 8) {
|
|
|
|
|
- createChip("Doc", systemImage: "doc.text", url: "https://docs.google.com/document/create")
|
|
|
|
|
- createChip("Sheet", systemImage: "tablecells", url: "https://sheets.google.com/spreadsheets/create")
|
|
|
|
|
- createChip("Slides", systemImage: "rectangle.on.rectangle", url: "https://slides.google.com/presentation/create")
|
|
|
|
|
- createChip("Form", systemImage: "list.bullet.rectangle", url: "https://docs.google.com/forms/create")
|
|
|
|
|
- Button(action: {
|
|
|
|
|
- NSApp.activate(ignoringOtherApps: true)
|
|
|
|
|
- openDrivePath("/drive/home")
|
|
|
|
|
- }) {
|
|
|
|
|
- HStack(spacing: 4) {
|
|
|
|
|
- Image(systemName: "arrow.up.doc")
|
|
|
|
|
- Text("Upload")
|
|
|
|
|
- }
|
|
|
|
|
- .font(.system(size: 10, weight: .bold))
|
|
|
|
|
- .foregroundStyle(.white.opacity(0.92))
|
|
|
|
|
- .padding(.horizontal, 10)
|
|
|
|
|
- .padding(.vertical, 6)
|
|
|
|
|
- .background(Capsule().fill(Color.white.opacity(0.14)))
|
|
|
|
|
- }
|
|
|
|
|
- .buttonStyle(.plain)
|
|
|
|
|
- .help("Open Drive to upload files")
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ private var quickFindChipsRow: some View {
|
|
|
|
|
+ ScrollView(.horizontal, showsIndicators: false) {
|
|
|
|
|
+ HStack(spacing: 8) {
|
|
|
|
|
+ driveChip("PDFs", path: "/drive/search?q=type:pdf")
|
|
|
|
|
+ driveChip("Images", path: "/drive/search?q=type:image")
|
|
|
|
|
+ driveChip("Videos", path: "/drive/search?q=type:video")
|
|
|
|
|
+ driveChip("Sheets", path: "/drive/search?q=type:spreadsheet")
|
|
|
|
|
+ driveChip("Docs", path: "/drive/search?q=type:document")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private func driveChip(_ title: String, path: String) -> some View {
|
|
|
|
|
|
|
+ private var createExpandedGrid: some View {
|
|
|
|
|
+ let cols = [GridItem(.flexible(minimum: 0), spacing: 8), GridItem(.flexible(minimum: 0), spacing: 8)]
|
|
|
|
|
+ return LazyVGrid(columns: cols, spacing: 8) {
|
|
|
|
|
+ createGridTile(title: "Doc", systemImage: "doc.text", url: "https://docs.google.com/document/create")
|
|
|
|
|
+ createGridTile(title: "Sheet", systemImage: "tablecells", url: "https://sheets.google.com/spreadsheets/create")
|
|
|
|
|
+ createGridTile(title: "Slides", systemImage: "rectangle.on.rectangle", url: "https://slides.google.com/presentation/create")
|
|
|
|
|
+ createGridTile(title: "Form", systemImage: "list.bullet.rectangle", url: "https://docs.google.com/forms/create")
|
|
|
|
|
+ createGridTile(title: "Drawing", systemImage: "pencil.and.outline", url: "https://docs.google.com/drawings/create")
|
|
|
|
|
+ createGridTile(title: "Sites", systemImage: "globe", url: "https://sites.google.com/new")
|
|
|
|
|
+ createGridTile(title: "Upload", systemImage: "arrow.up.doc", path: "/drive/home")
|
|
|
|
|
+ createGridTile(title: "Folder", systemImage: "folder.badge.plus", path: "/drive/home")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private var moreToolsRow: some View {
|
|
|
|
|
+ ScrollView(.horizontal, showsIndicators: false) {
|
|
|
|
|
+ HStack(spacing: 8) {
|
|
|
|
|
+ driveChip("Storage", path: "/settings/storage")
|
|
|
|
|
+ driveChip("Settings", path: "/drive/settings")
|
|
|
|
|
+ driveChip("Activity", path: "/drive/home")
|
|
|
|
|
+ driveChip("Gemini", path: "https://gemini.google.com/app")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private func createGridTile(title: String, systemImage: String, url: String) -> some View {
|
|
|
Button(action: {
|
|
Button(action: {
|
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
|
- navigateWeb(to: path)
|
|
|
|
|
|
|
+ guard let u = URL(string: url) else { return }
|
|
|
|
|
+ InAppBrowserWindowManager.shared.open(url: u, title: app.name)
|
|
|
}) {
|
|
}) {
|
|
|
- Text(title)
|
|
|
|
|
- .font(.system(size: 10, weight: .bold))
|
|
|
|
|
- .foregroundStyle(.white.opacity(0.92))
|
|
|
|
|
- .padding(.horizontal, 10)
|
|
|
|
|
- .padding(.vertical, 6)
|
|
|
|
|
- .background(Capsule().fill(Color.white.opacity(0.12)))
|
|
|
|
|
|
|
+ HStack(spacing: 8) {
|
|
|
|
|
+ Image(systemName: systemImage)
|
|
|
|
|
+ .font(.system(size: 14, weight: .semibold))
|
|
|
|
|
+ .foregroundStyle(Color(red: 0.75, green: 0.92, blue: 0.82))
|
|
|
|
|
+ Text(title)
|
|
|
|
|
+ .font(.system(size: 12, weight: .bold))
|
|
|
|
|
+ .foregroundStyle(.white.opacity(0.95))
|
|
|
|
|
+ Spacer(minLength: 0)
|
|
|
|
|
+ }
|
|
|
|
|
+ .padding(.horizontal, 12)
|
|
|
|
|
+ .padding(.vertical, 10)
|
|
|
|
|
+ .background(RoundedRectangle(cornerRadius: 12, style: .continuous).fill(Color.black.opacity(0.28)))
|
|
|
}
|
|
}
|
|
|
.buttonStyle(.plain)
|
|
.buttonStyle(.plain)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private func createChip(_ title: String, systemImage: String, url: String) -> some View {
|
|
|
|
|
|
|
+ private func createGridTile(title: String, systemImage: String, path: String) -> some View {
|
|
|
Button(action: {
|
|
Button(action: {
|
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
|
- guard let u = URL(string: url) else { return }
|
|
|
|
|
- InAppBrowserWindowManager.shared.open(url: u, title: app.name)
|
|
|
|
|
|
|
+ openDrivePath(path)
|
|
|
}) {
|
|
}) {
|
|
|
- HStack(spacing: 4) {
|
|
|
|
|
|
|
+ HStack(spacing: 8) {
|
|
|
Image(systemName: systemImage)
|
|
Image(systemName: systemImage)
|
|
|
- .font(.system(size: 10, weight: .semibold))
|
|
|
|
|
|
|
+ .font(.system(size: 14, weight: .semibold))
|
|
|
|
|
+ .foregroundStyle(Color(red: 0.75, green: 0.92, blue: 0.82))
|
|
|
Text(title)
|
|
Text(title)
|
|
|
- .font(.system(size: 10, weight: .bold))
|
|
|
|
|
|
|
+ .font(.system(size: 12, weight: .bold))
|
|
|
|
|
+ .foregroundStyle(.white.opacity(0.95))
|
|
|
|
|
+ Spacer(minLength: 0)
|
|
|
}
|
|
}
|
|
|
- .foregroundStyle(.white.opacity(0.92))
|
|
|
|
|
- .padding(.horizontal, 10)
|
|
|
|
|
- .padding(.vertical, 6)
|
|
|
|
|
- .background(Capsule().fill(Color.white.opacity(0.12)))
|
|
|
|
|
|
|
+ .padding(.horizontal, 12)
|
|
|
|
|
+ .padding(.vertical, 10)
|
|
|
|
|
+ .background(RoundedRectangle(cornerRadius: 12, style: .continuous).fill(Color.black.opacity(0.28)))
|
|
|
|
|
+ }
|
|
|
|
|
+ .buttonStyle(.plain)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private func driveChip(_ title: String, path: String) -> some View {
|
|
|
|
|
+ Button(action: {
|
|
|
|
|
+ NSApp.activate(ignoringOtherApps: true)
|
|
|
|
|
+ if path.hasPrefix("http://") || path.hasPrefix("https://") {
|
|
|
|
|
+ if let u = URL(string: path) {
|
|
|
|
|
+ InAppBrowserWindowManager.shared.open(url: u, title: app.name)
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ openDrivePath(path)
|
|
|
|
|
+ }
|
|
|
|
|
+ }) {
|
|
|
|
|
+ Text(title)
|
|
|
|
|
+ .font(.system(size: 10, weight: .bold))
|
|
|
|
|
+ .foregroundStyle(.white.opacity(0.92))
|
|
|
|
|
+ .padding(.horizontal, 10)
|
|
|
|
|
+ .padding(.vertical, 6)
|
|
|
|
|
+ .background(Capsule().fill(Color.white.opacity(0.12)))
|
|
|
}
|
|
}
|
|
|
.buttonStyle(.plain)
|
|
.buttonStyle(.plain)
|
|
|
}
|
|
}
|
|
@@ -507,108 +538,11 @@ struct DriveDesktopWidgetView: View {
|
|
|
openDrivePath(path)
|
|
openDrivePath(path)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private func navigateWeb(to path: String) {
|
|
|
|
|
- let url = WidgetDeepLinkURL.resolved(base: baseURL, actionPath: path, accountSlot: 0)
|
|
|
|
|
- DispatchQueue.main.async {
|
|
|
|
|
- webURL = url
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private func submitSearch() {
|
|
private func submitSearch() {
|
|
|
let q = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
let q = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
|
guard !q.isEmpty else { return }
|
|
guard !q.isEmpty else { return }
|
|
|
|
|
+ NSApp.activate(ignoringOtherApps: true)
|
|
|
let encoded = q.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? q
|
|
let encoded = q.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? q
|
|
|
- navigateWeb(to: "/drive/search?q=\(encoded)")
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// MARK: - WKWebView
|
|
|
|
|
-
|
|
|
|
|
-private final class DriveWebViewClippingContainer: NSView {
|
|
|
|
|
- override var isFlipped: Bool { true }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-private struct DriveWebWidgetView: NSViewRepresentable {
|
|
|
|
|
- @Binding var url: URL
|
|
|
|
|
-
|
|
|
|
|
- func makeCoordinator() -> Coordinator {
|
|
|
|
|
- Coordinator()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- func makeNSView(context: Context) -> NSView {
|
|
|
|
|
- let container = DriveWebViewClippingContainer()
|
|
|
|
|
- container.wantsLayer = true
|
|
|
|
|
- container.layer?.masksToBounds = true
|
|
|
|
|
- container.layer?.cornerRadius = 12
|
|
|
|
|
- container.layer?.borderWidth = 0
|
|
|
|
|
-
|
|
|
|
|
- let config = WKWebViewConfiguration()
|
|
|
|
|
- config.defaultWebpagePreferences.allowsContentJavaScript = true
|
|
|
|
|
- let wv = WKWebView(frame: .zero, configuration: config)
|
|
|
|
|
- wv.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
|
- wv.focusRingType = .none
|
|
|
|
|
- wv.customUserAgent =
|
|
|
|
|
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15"
|
|
|
|
|
- wv.navigationDelegate = context.coordinator
|
|
|
|
|
-
|
|
|
|
|
- container.addSubview(wv)
|
|
|
|
|
- NSLayoutConstraint.activate([
|
|
|
|
|
- wv.leadingAnchor.constraint(equalTo: container.leadingAnchor),
|
|
|
|
|
- wv.trailingAnchor.constraint(equalTo: container.trailingAnchor),
|
|
|
|
|
- wv.topAnchor.constraint(equalTo: container.topAnchor),
|
|
|
|
|
- wv.bottomAnchor.constraint(equalTo: container.bottomAnchor),
|
|
|
|
|
- ])
|
|
|
|
|
-
|
|
|
|
|
- context.coordinator.webView = wv
|
|
|
|
|
- context.coordinator.lastLoadedURLString = url.absoluteString
|
|
|
|
|
- wv.load(URLRequest(url: url))
|
|
|
|
|
- DispatchQueue.main.async {
|
|
|
|
|
- Self.stripWebKitOuterChrome(wv)
|
|
|
|
|
- }
|
|
|
|
|
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
|
|
|
|
|
- Self.stripWebKitOuterChrome(wv)
|
|
|
|
|
- }
|
|
|
|
|
- return container
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- func updateNSView(_ container: NSView, context: Context) {
|
|
|
|
|
- guard let wv = context.coordinator.webView else { return }
|
|
|
|
|
- let next = url.absoluteString
|
|
|
|
|
- guard context.coordinator.lastLoadedURLString != next else { return }
|
|
|
|
|
- context.coordinator.lastLoadedURLString = next
|
|
|
|
|
- wv.load(URLRequest(url: url))
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private static func stripWebKitOuterChrome(_ webView: WKWebView) {
|
|
|
|
|
- webView.focusRingType = .none
|
|
|
|
|
- func walk(_ view: NSView) {
|
|
|
|
|
- view.focusRingType = .none
|
|
|
|
|
- view.layer?.borderWidth = 0
|
|
|
|
|
- view.layer?.borderColor = NSColor.clear.cgColor
|
|
|
|
|
- if let scroll = view as? NSScrollView {
|
|
|
|
|
- scroll.borderType = .noBorder
|
|
|
|
|
- scroll.drawsBackground = false
|
|
|
|
|
- scroll.scrollerStyle = .overlay
|
|
|
|
|
- }
|
|
|
|
|
- if let clip = view as? NSClipView {
|
|
|
|
|
- clip.drawsBackground = false
|
|
|
|
|
- }
|
|
|
|
|
- for sub in view.subviews {
|
|
|
|
|
- walk(sub)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- walk(webView)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- final class Coordinator: NSObject, WKNavigationDelegate {
|
|
|
|
|
- weak var webView: WKWebView?
|
|
|
|
|
- var lastLoadedURLString: String?
|
|
|
|
|
-
|
|
|
|
|
- func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
|
|
|
- DriveWebWidgetView.stripWebKitOuterChrome(webView)
|
|
|
|
|
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
|
|
|
|
|
- DriveWebWidgetView.stripWebKitOuterChrome(webView)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ openDrivePath("/drive/search?q=\(encoded)")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|