ソースを参照

Improved Dashboard

Signed-off-by: marinofaggiana <marino.faggiana@nextcloud.com>
marinofaggiana 2 年 前
コミット
795794d1a6

+ 34 - 6
Nextcloud.xcodeproj/project.pbxproj

@@ -164,6 +164,10 @@
 		F72D404923D2082500A97FD0 /* NCViewerNextcloudText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72D404823D2082500A97FD0 /* NCViewerNextcloudText.swift */; };
 		F72D7EB7263B1207000B3DFC /* MarkdownKit in Frameworks */ = {isa = PBXBuildFile; productRef = F72D7EB6263B1207000B3DFC /* MarkdownKit */; };
 		F72DA9B425F53E4E00B87DB1 /* SwiftRichString in Frameworks */ = {isa = PBXBuildFile; productRef = F72DA9B325F53E4E00B87DB1 /* SwiftRichString */; };
+		F72EA95228B7BA2A00C88F0C /* DashboardWidgetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72EA95128B7BA2A00C88F0C /* DashboardWidgetProvider.swift */; };
+		F72EA95428B7BABA00C88F0C /* NextcloudWidgetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72EA95328B7BABA00C88F0C /* NextcloudWidgetProvider.swift */; };
+		F72EA95828B7BC4F00C88F0C /* NextcloudData.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72EA95728B7BC4F00C88F0C /* NextcloudData.swift */; };
+		F72EA95A28B7BD0D00C88F0C /* NextcloudWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F72EA95928B7BD0D00C88F0C /* NextcloudWidgetView.swift */; };
 		F732D23327CF8AED000B0F1B /* NCPlayerToolBar.xib in Resources */ = {isa = PBXBuildFile; fileRef = F732D23227CF8AED000B0F1B /* NCPlayerToolBar.xib */; };
 		F733598125C1C188002ABA72 /* NCAskAuthorization.swift in Sources */ = {isa = PBXBuildFile; fileRef = F733598025C1C188002ABA72 /* NCAskAuthorization.swift */; };
 		F7346E1228B0EF5B006CE2D2 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7346E1128B0EF5B006CE2D2 /* WidgetKit.framework */; };
@@ -192,7 +196,6 @@
 		F73D5E49246DE09200DF6467 /* NCElementsJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73D5E46246DE09200DF6467 /* NCElementsJSON.swift */; };
 		F73D5E4A246DE09200DF6467 /* NCElementsJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73D5E46246DE09200DF6467 /* NCElementsJSON.swift */; };
 		F73F537F1E929C8500F8678D /* NCMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73F537E1E929C8500F8678D /* NCMore.swift */; };
-		F741F3B628B3D5720045394D /* DashboardNetworking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F741F3B528B3D5720045394D /* DashboardNetworking.swift */; };
 		F7434B3420E23FD700417916 /* NCDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BAADB41ED5A87C00B7EAD4 /* NCDatabase.swift */; };
 		F7434B3620E23FE000417916 /* NCManageDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7BAADB51ED5A87C00B7EAD4 /* NCManageDatabase.swift */; };
 		F7434B3820E2400600417916 /* NCBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76B3CCD1EAE01BD00921AC9 /* NCBrand.swift */; };
@@ -718,6 +721,10 @@
 		F72D1006210B6882009C96B7 /* NCPushNotificationEncryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCPushNotificationEncryption.h; sourceTree = "<group>"; };
 		F72D404823D2082500A97FD0 /* NCViewerNextcloudText.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCViewerNextcloudText.swift; sourceTree = "<group>"; };
 		F72E0B9C21AD60BC00898D7B /* WeScan.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WeScan.framework; path = Carthage/Build/iOS/WeScan.framework; sourceTree = "<group>"; };
+		F72EA95128B7BA2A00C88F0C /* DashboardWidgetProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardWidgetProvider.swift; sourceTree = "<group>"; };
+		F72EA95328B7BABA00C88F0C /* NextcloudWidgetProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextcloudWidgetProvider.swift; sourceTree = "<group>"; };
+		F72EA95728B7BC4F00C88F0C /* NextcloudData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextcloudData.swift; sourceTree = "<group>"; };
+		F72EA95928B7BD0D00C88F0C /* NextcloudWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextcloudWidgetView.swift; sourceTree = "<group>"; };
 		F7320934201B812F008A0888 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = "<group>"; };
 		F732093B201B81E4008A0888 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F732D23227CF8AED000B0F1B /* NCPlayerToolBar.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCPlayerToolBar.xib; sourceTree = "<group>"; };
@@ -743,7 +750,6 @@
 		F73D11F9253C5F4800DF9BEC /* NCViewerNextcloudText.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCViewerNextcloudText.storyboard; sourceTree = "<group>"; };
 		F73D5E46246DE09200DF6467 /* NCElementsJSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCElementsJSON.swift; sourceTree = "<group>"; };
 		F73F537E1E929C8500F8678D /* NCMore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCMore.swift; sourceTree = "<group>"; };
-		F741F3B528B3D5720045394D /* DashboardNetworking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardNetworking.swift; sourceTree = "<group>"; };
 		F7421EAE2294044B00C4B7C1 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
 		F7434B5F20E2440600417916 /* FileProviderExtension-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FileProviderExtension-Bridging-Header.h"; sourceTree = "<group>"; };
 		F745B250222D871800346520 /* QRCodeReader.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QRCodeReader.framework; path = Carthage/Build/iOS/QRCodeReader.framework; sourceTree = "<group>"; };
@@ -1347,13 +1353,32 @@
 			name = Localizations;
 			sourceTree = "<group>";
 		};
-		F7346E1428B0EF5B006CE2D2 /* Widget */ = {
+		F72EA95528B7BAD100C88F0C /* Dashboard */ = {
 			isa = PBXGroup;
 			children = (
-				F7346E2228B0FEBA006CE2D2 /* Assets.xcassets */,
 				F7E0710028B13BB00001B882 /* DashboardData.swift */,
-				F741F3B528B3D5720045394D /* DashboardNetworking.swift */,
+				F72EA95128B7BA2A00C88F0C /* DashboardWidgetProvider.swift */,
 				F72A17D728B221E300F3F159 /* DashboardWidgetView.swift */,
+			);
+			path = Dashboard;
+			sourceTree = "<group>";
+		};
+		F72EA95628B7BAE700C88F0C /* Nextcloud */ = {
+			isa = PBXGroup;
+			children = (
+				F72EA95728B7BC4F00C88F0C /* NextcloudData.swift */,
+				F72EA95328B7BABA00C88F0C /* NextcloudWidgetProvider.swift */,
+				F72EA95928B7BD0D00C88F0C /* NextcloudWidgetView.swift */,
+			);
+			path = Nextcloud;
+			sourceTree = "<group>";
+		};
+		F7346E1428B0EF5B006CE2D2 /* Widget */ = {
+			isa = PBXGroup;
+			children = (
+				F7346E2228B0FEBA006CE2D2 /* Assets.xcassets */,
+				F72EA95528B7BAD100C88F0C /* Dashboard */,
+				F72EA95628B7BAE700C88F0C /* Nextcloud */,
 				F7346E2028B0FA3A006CE2D2 /* Widget-Brinding-header.h */,
 				F7346E1528B0EF5C006CE2D2 /* Widget.swift */,
 			);
@@ -2649,12 +2674,12 @@
 				F793E5A128B76541005E4B02 /* NotificationCenter+MainThread.swift in Sources */,
 				F78302F928B4C3E600B84583 /* NCManageDatabase+Account.swift in Sources */,
 				F7E0710128B13BB00001B882 /* DashboardData.swift in Sources */,
-				F741F3B628B3D5720045394D /* DashboardNetworking.swift in Sources */,
 				F783030328B4C4DD00B84583 /* ThreadSafeDictionary.swift in Sources */,
 				F78302F728B4C3C900B84583 /* NCManageDatabase.swift in Sources */,
 				F7346E1628B0EF5C006CE2D2 /* Widget.swift in Sources */,
 				F78302F828B4C3E100B84583 /* NCManageDatabase+Activity.swift in Sources */,
 				F783030228B4C4B800B84583 /* NCUtility.swift in Sources */,
+				F72EA95A28B7BD0D00C88F0C /* NextcloudWidgetView.swift in Sources */,
 				F78302FE28B4C44700B84583 /* NCBrand.swift in Sources */,
 				F793E5A028B7651B005E4B02 /* NCViewCertificateDetails.swift in Sources */,
 				F793E59F28B764F6005E4B02 /* NCContentPresenter.swift in Sources */,
@@ -2668,12 +2693,15 @@
 				F72A17D828B221E300F3F159 /* DashboardWidgetView.swift in Sources */,
 				F793E59B28B75FB0005E4B02 /* NCAutoUpload.swift in Sources */,
 				F78302FB28B4C3EE00B84583 /* NCManageDatabase+Video.swift in Sources */,
+				F72EA95228B7BA2A00C88F0C /* DashboardWidgetProvider.swift in Sources */,
 				F793E5A228B76580005E4B02 /* NCNetworkingChunkedUpload.swift in Sources */,
 				F783031228B4C8EC00B84583 /* CCUtility.m in Sources */,
+				F72EA95828B7BC4F00C88F0C /* NextcloudData.swift in Sources */,
 				F793E59E28B763C2005E4B02 /* NCAskAuthorization.swift in Sources */,
 				F78302FF28B4C45000B84583 /* NCUtilityFileSystem.swift in Sources */,
 				F78302F628B4C3C500B84583 /* NCDatabase.swift in Sources */,
 				F783030128B4C49700B84583 /* UIImage+Extensions.swift in Sources */,
+				F72EA95428B7BABA00C88F0C /* NextcloudWidgetProvider.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 41 - 4
Widget/DashboardNetworking.swift → Widget/Dashboard/DashboardData.swift

@@ -1,8 +1,8 @@
 //
-//  DashboardNetworking.swift
+//  DashboardData.swift
 //  Widget
 //
-//  Created by Marino Faggiana on 22/08/22.
+//  Created by Marino Faggiana on 20/08/22.
 //  Copyright © 2022 Marino Faggiana. All rights reserved.
 //
 //  Author Marino Faggiana <marino.faggiana@nextcloud.com>
@@ -21,9 +21,25 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-import Foundation
+import WidgetKit
 import NextcloudKit
 
+struct DashboardData: Identifiable, Codable, Hashable {
+    var id: Int
+    var image: String
+    var title: String
+    var subTitle: String
+    var url: URL
+}
+
+struct DashboardDataEntry: TimelineEntry {
+    let date: Date
+    let dashboardDatas: [DashboardData]
+    let isPlaceholder: Bool
+    let title: String
+    let footerText: String
+}
+
 let dashboardDatasTest: [DashboardData] = [
     .init(id: 0, image: "nextcloud", title: "title 1", subTitle: "subTitle - description 1", url: URL(string: "https://nextcloud.com/")!),
     .init(id: 1, image: "nextcloud", title: "title 2", subTitle: "subTitle - description 2", url: URL(string: "https://nextcloud.com/")!),
@@ -32,7 +48,27 @@ let dashboardDatasTest: [DashboardData] = [
     .init(id: 4, image: "nextcloud", title: "title 5", subTitle: "subTitle - description 5", url: URL(string: "https://nextcloud.com/")!)
 ]
 
-func readDashboard(completion: @escaping (_ dashboardData: [DashboardData], _ isPlaceholder: Bool, _ title: String, _ footerText: String) -> Void) {
+func getTitle(account: tableAccount?) -> String {
+
+    let hour = Calendar.current.component(.hour, from: Date())
+    var good = ""
+
+    switch hour {
+    case 6..<12: good = NSLocalizedString("_good_morning_", value: "Good morning", comment: "")
+    case 12: good = NSLocalizedString("_good_noon_", value: "Good noon", comment: "")
+    case 13..<17: good = NSLocalizedString("_good_afternoon_", value: "Good afternoon", comment: "")
+    case 17..<22: good = NSLocalizedString("_good_evening_", value: "Good evening", comment: "")
+    default: good = NSLocalizedString("_good_night_", value: "Good night", comment: "")
+    }
+
+    if let account = account {
+        return good + ", " + account.displayName
+    } else {
+        return good
+    }
+}
+
+func readDashboardData(completion: @escaping (_ dashboardData: [DashboardData], _ isPlaceholder: Bool, _ title: String, _ footerText: String) -> Void) {
 
     guard let account = NCManageDatabase.shared.getActiveAccount() else {
         return completion(dashboardDatasTest, true, getTitle(account: nil), NSLocalizedString("_no_active_account_", value: "No account found", comment: ""))
@@ -59,3 +95,4 @@ func readDashboard(completion: @escaping (_ dashboardData: [DashboardData], _ is
         NKCommon.shared.writeLog("Completition Dashboard widget [Auto upload]")
     }
 }
+

+ 47 - 0
Widget/Dashboard/DashboardWidgetProvider.swift

@@ -0,0 +1,47 @@
+//
+//  DashboardWidgetProvider.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import WidgetKit
+import SwiftUI
+
+struct DashboardWidgetProvider: TimelineProvider {
+
+    typealias Entry = DashboardDataEntry
+
+    func placeholder(in context: Context) -> Entry {
+        return Entry(date: Date(), dashboardDatas: dashboardDatasTest, isPlaceholder: true, title: getTitle(account: nil), footerText: "Nextcloud Dashboard")
+    }
+
+    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
+        readDashboardData { dashboardDatas, isPlaceholder, title, footerText in
+            completion(Entry(date: Date(), dashboardDatas: dashboardDatas, isPlaceholder: isPlaceholder, title: title, footerText: footerText))
+        }
+    }
+
+    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
+        readDashboardData { dashboardDatas, isPlaceholder, title, footerText in
+            let timeLine = Timeline(entries: [Entry(date: Date(), dashboardDatas: dashboardDatas, isPlaceholder: isPlaceholder, title: title, footerText: footerText)], policy: .atEnd)
+            completion(timeLine)
+        }
+    }
+}

+ 1 - 1
Widget/DashboardWidgetView.swift → Widget/Dashboard/DashboardWidgetView.swift

@@ -82,7 +82,7 @@ struct DashboardWidgetView: View {
     }
 }
 
-struct NCElementDashboard_Previews: PreviewProvider {
+struct DashboardWidget_Previews: PreviewProvider {
     static var previews: some View {
         let entry = DashboardDataEntry(date: Date(), dashboardDatas: dashboardDatasTest, isPlaceholder: false, title: getTitle(account: nil), footerText: "Nextcloud Dashboard")
         DashboardWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge))

+ 0 - 60
Widget/DashboardData.swift

@@ -1,60 +0,0 @@
-//
-//  DashboardData.swift
-//  Widget
-//
-//  Created by Marino Faggiana on 20/08/22.
-//  Copyright © 2022 Marino Faggiana. All rights reserved.
-//
-//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
-//
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-//
-
-import WidgetKit
-
-struct DashboardData: Identifiable, Codable, Hashable {
-    var id: Int
-    var image: String
-    var title: String
-    var subTitle: String
-    var url: URL
-}
-
-struct DashboardDataEntry: TimelineEntry {
-    let date: Date
-    let dashboardDatas: [DashboardData]
-    let isPlaceholder: Bool
-    let title: String
-    let footerText: String
-}
-
-func getTitle(account: tableAccount?) -> String {
-
-    let hour = Calendar.current.component(.hour, from: Date())
-    var good = ""
-
-    switch hour {
-    case 6..<12: good = NSLocalizedString("_good_morning_", value: "Good morning", comment: "")
-    case 12: good = NSLocalizedString("_good_noon_", value: "Good noon", comment: "")
-    case 13..<17: good = NSLocalizedString("_good_afternoon_", value: "Good afternoon", comment: "")
-    case 17..<22: good = NSLocalizedString("_good_evening_", value: "Good evening", comment: "")
-    default: good = NSLocalizedString("_good_night_", value: "Good night", comment: "")
-    }
-
-    if let account = account {
-        return good + ", " + account.displayName
-    } else {
-        return good
-    }
-}

+ 52 - 0
Widget/Nextcloud/NextcloudData.swift

@@ -0,0 +1,52 @@
+//
+//  NextcloudData.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import WidgetKit
+import NextcloudKit
+
+struct NextcloudData: Identifiable, Codable, Hashable {
+    var id: Int
+    var image: String
+    var title: String
+    var subTitle: String
+    var url: URL
+}
+
+struct NextcloudDataEntry: TimelineEntry {
+    let date: Date
+    let nextcloudDatas: [NextcloudData]
+    let isPlaceholder: Bool
+    let footerText: String
+}
+
+let nextcloudDatasTest: [NextcloudData] = [
+    .init(id: 0, image: "nextcloud", title: "title 1", subTitle: "subTitle - description 1", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: 1, image: "nextcloud", title: "title 2", subTitle: "subTitle - description 2", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: 2, image: "nextcloud", title: "title 3", subTitle: "subTitle - description 3", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: 3, image: "nextcloud", title: "title 4", subTitle: "subTitle - description 4", url: URL(string: "https://nextcloud.com/")!),
+    .init(id: 4, image: "nextcloud", title: "title 5", subTitle: "subTitle - description 5", url: URL(string: "https://nextcloud.com/")!)
+]
+
+func readNextcloudData(completion: @escaping (_ NextcloudDatas: [NextcloudData], _ isPlaceholder: Bool, _ footerText: String) -> Void) {
+
+}

+ 47 - 0
Widget/Nextcloud/NextcloudWidgetProvider.swift

@@ -0,0 +1,47 @@
+//
+//  NextcloudWidgetProvider.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import WidgetKit
+import SwiftUI
+
+struct NextcloudWidgetProvider: TimelineProvider {
+
+    typealias Entry = NextcloudDataEntry
+
+    func placeholder(in context: Context) -> Entry {
+        return Entry(date: Date(), nextcloudDatas: nextcloudDatasTest, isPlaceholder: true, footerText: "Nextcloud")
+    }
+
+    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
+        readNextcloudData { nextcloudDatas, isPlaceholder, footerText in
+            completion(Entry(date: Date(), nextcloudDatas: nextcloudDatas, isPlaceholder: isPlaceholder, footerText: footerText))
+        }
+    }
+
+    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
+        readNextcloudData { nextcloudDatas, isPlaceholder, footerText in
+            let timeLine = Timeline(entries: [Entry(date: Date(), nextcloudDatas: nextcloudDatas, isPlaceholder: isPlaceholder, footerText: footerText)], policy: .atEnd)
+            completion(timeLine)
+        }
+    }
+}

+ 73 - 0
Widget/Nextcloud/NextcloudWidgetView.swift

@@ -0,0 +1,73 @@
+//
+//  NextcloudWidgetView.swift
+//  Widget
+//
+//  Created by Marino Faggiana on 25/08/22.
+//  Copyright © 2022 Marino Faggiana. All rights reserved.
+//
+//  Author Marino Faggiana <marino.faggiana@nextcloud.com>
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import SwiftUI
+import WidgetKit
+
+struct NextcloudWidgetView: View {
+    var entry: NextcloudDataEntry
+    var body: some View {
+        ZStack {
+            VStack {
+                Text(NCBrandOptions.shared.brand)
+                    .font(.title3)
+                    .bold()
+                    .fixedSize(horizontal: false, vertical: true)
+                VStack(spacing: 5) {
+                    ForEach(entry.nextcloudDatas, id: \.id) { element in
+                        Link(destination: element.url) {
+                            HStack {
+                                Image(element.image)
+                                    .resizable()
+                                    .aspectRatio(contentMode: .fit)
+                                    .frame(width: 40, height: 40)
+                                    .clipShape(Circle())
+                                VStack(alignment: .leading) {
+                                    Text(element.title)
+                                        .font(.headline)
+                                    Text(element.subTitle)
+                                        .font(.subheadline)
+                                        .foregroundColor(Color(white: 0.4745))
+                                }
+                                Spacer()
+                            }
+                            .padding(5)
+                        }
+                    }
+                }
+            }.padding(5)
+                .redacted(reason: entry.isPlaceholder ? .placeholder : [])
+            }
+        Text(entry.footerText)
+                .font(.caption2)
+                .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomTrailing)
+                .padding([.bottom, .trailing], 5.0)
+    }
+}
+
+struct NextcloudWidget_Previews: PreviewProvider {
+    static var previews: some View {
+        let entry = NextcloudDataEntry(date: Date(), nextcloudDatas: nextcloudDatasTest, isPlaceholder: false, footerText: "Nextcloud Dashboard")
+        NextcloudWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge))
+    }
+}

+ 15 - 31
Widget/Widget.swift

@@ -24,54 +24,38 @@
 import WidgetKit
 import SwiftUI
 
-struct Provider: TimelineProvider {
-
-    typealias Entry = DashboardDataEntry
-
-    func placeholder(in context: Context) -> Entry {
-        return Entry(date: Date(), dashboardDatas: [], isPlaceholder: true, title: getTitle(account: nil), footerText: "Nextcloud Dashboard")
-    }
-
-    func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
-        readDashboard { dashboardDatas, isPlaceholder, title, footerText in
-            completion(Entry(date: Date(), dashboardDatas: dashboardDatas, isPlaceholder: isPlaceholder, title: title, footerText: footerText))
-        }
-    }
-
-    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
-        readDashboard { dashboardDatas, isPlaceholder, title, footerText in
-            let timeLine = Timeline(entries: [Entry(date: Date(), dashboardDatas: dashboardDatas, isPlaceholder: isPlaceholder, title: title, footerText: footerText)], policy: .atEnd)
-            completion(timeLine)
-        }
-    }
-}
-
 @main
-struct NextcloudWidget: WidgetBundle {
+struct NextcloudWidgetBundle: WidgetBundle {
 
     @WidgetBundleBuilder
     var body: some Widget {
         DashboardWidget()
+        NextcloudWidget()
     }
 }
 
 struct DashboardWidget: Widget {
-    let kind: String = "NextcloudWidget"
+    let kind: String = "DashboardWidget"
 
     var body: some WidgetConfiguration {
-        StaticConfiguration(kind: kind, provider: Provider()) { entry in
+        StaticConfiguration(kind: kind, provider: DashboardWidgetProvider()) { entry in
             DashboardWidgetView(entry: entry)
         }
         .supportedFamilies([.systemLarge])
-        .configurationDisplayName("Nextcloud Dashboard")
-        .description(NSLocalizedString("_subtitle_dashboard_", comment: ""))
+        .configurationDisplayName("Dashboard")
+        .description(NSLocalizedString("_description_dashboardwidget_", comment: ""))
     }
 }
 
-struct DashboardWidget_Previews: PreviewProvider {
+struct NextcloudWidget: Widget {
+    let kind: String = "NextcloudWidget"
 
-    static var previews: some View {
-        let entry = DashboardDataEntry(date: Date(), dashboardDatas: dashboardDatasTest, isPlaceholder: false, title: getTitle(account: nil), footerText: "Nextcloud Dashboard")
-        DashboardWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge))
+    var body: some WidgetConfiguration {
+        StaticConfiguration(kind: kind, provider: NextcloudWidgetProvider()) { entry in
+            NextcloudWidgetView(entry: entry)
+        }
+        .supportedFamilies([.systemLarge])
+        .configurationDisplayName(NCBrandOptions.shared.brand)
+        .description(NSLocalizedString("_description_nextcloudwidget_", comment: ""))
     }
 }