[WIP] Fix widget data

This commit is contained in:
Ali
2020-10-18 03:45:39 +04:00
parent 517fcabed9
commit ed7d110c94
2 changed files with 62 additions and 40 deletions

View File

@@ -26,7 +26,7 @@ struct Provider: TimelineProvider {
var entries: [SimpleEntry] = [] var entries: [SimpleEntry] = []
let currentDate = Date() let currentDate = Date()
for hourOffset in 0 ..< 5 { for hourOffset in 0 ..< 1 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate) let entry = SimpleEntry(date: entryDate)
entries.append(entry) entries.append(entry)
@@ -38,19 +38,13 @@ struct Provider: TimelineProvider {
} }
struct SimpleEntry: TimelineEntry { struct SimpleEntry: TimelineEntry {
public let date: Date let date: Date
}
struct Static_WidgetEntryView: View {
var entry: Provider.Entry
var body: some View {
Text(entry.date, style: .time)
}
} }
enum PeersWidgetData { enum PeersWidgetData {
case placeholder case placeholder
case empty
case locked
case data(WidgetData) case data(WidgetData)
} }
@@ -61,7 +55,7 @@ extension PeersWidgetData {
struct WidgetView: View { struct WidgetView: View {
let data: PeersWidgetData let data: PeersWidgetData
func peerViews(geometry: GeometryProxy) -> AnyView { func placeholder(geometry: GeometryProxy) -> some View {
let defaultItemSize: CGFloat = 60.0 let defaultItemSize: CGFloat = 60.0
let defaultPaddingFraction: CGFloat = 0.36 let defaultPaddingFraction: CGFloat = 0.36
@@ -71,24 +65,53 @@ struct WidgetView: View {
let firstRowY = itemSize / 2.0 let firstRowY = itemSize / 2.0
let secondRowY = itemSize / 2.0 + geometry.size.height - itemSize let secondRowY = itemSize / 2.0 + geometry.size.height - itemSize
return ZStack {
ForEach(0 ..< rowCount * 2, content: { i in
return Circle().frame(width: itemSize, height: itemSize).position(x: itemSize / 2.0 + floor(CGFloat(i % rowCount) * itemSize * (1.0 + defaultPaddingFraction)), y: i / rowCount == 0 ? firstRowY : secondRowY).foregroundColor(.gray)
})
}
}
func peersView(geometry: GeometryProxy, peers: WidgetDataPeers) -> some View {
let defaultItemSize: CGFloat = 60.0
let defaultPaddingFraction: CGFloat = 0.36
let rowCount = Int(round(geometry.size.width / (defaultItemSize * (1.0 + defaultPaddingFraction))))
let itemSize = floor(geometry.size.width / (CGFloat(rowCount) + defaultPaddingFraction * CGFloat(rowCount - 1)))
let firstRowY = itemSize / 2.0
let secondRowY = itemSize / 2.0 + geometry.size.height - itemSize
return ZStack {
ForEach(0 ..< min(peers.peers.count, rowCount * 2), content: { i in
Link(destination: URL(string: "\(buildConfig.appSpecificUrlScheme)://localpeer?id=\(peers.peers[i].id)")!, label: {
Image(uiImage: avatarImage(accountPeerId: peers.accountPeerId, peer: peers.peers[i], size: CGSize(width: itemSize, height: itemSize)))
.frame(width: itemSize, height: itemSize)
}).frame(width: itemSize, height: itemSize)
.position(x: itemSize / 2.0 + floor(CGFloat(i % rowCount) * itemSize * (1.0 + defaultPaddingFraction)), y: i / rowCount == 0 ? firstRowY : secondRowY)
})
}
}
func peerViews() -> AnyView {
switch data { switch data {
case .placeholder: case .placeholder:
return AnyView(ZStack { return AnyView(GeometryReader { geometry in
ForEach(0 ..< rowCount * 2, content: { i in placeholder(geometry: geometry)
return Circle().frame(width: itemSize, height: itemSize).position(x: itemSize / 2.0 + floor(CGFloat(i % rowCount) * itemSize * (1.0 + defaultPaddingFraction)), y: i / rowCount == 0 ? firstRowY : secondRowY).foregroundColor(.gray) })
}) case .empty:
return AnyView(VStack {
Text(presentationData.applicationStartRequiredString)
})
case .locked:
return AnyView(VStack {
Text(presentationData.applicationLockedString)
}) })
case let .data(data): case let .data(data):
switch data { switch data {
case let .peers(peers): case let .peers(peers):
return AnyView(ZStack { return AnyView(GeometryReader { geometry in
ForEach(0 ..< min(peers.peers.count, rowCount * 2), content: { i in peersView(geometry: geometry, peers: peers)
Link(destination: URL(string: "\(buildConfig.appSpecificUrlScheme)://localpeer?id=\(peers.peers[i].id)")!, label: {
Image(uiImage: avatarImage(accountPeerId: peers.accountPeerId, peer: peers.peers[i], size: CGSize(width: itemSize, height: itemSize)))
.frame(width: itemSize, height: itemSize)
}).frame(width: itemSize, height: itemSize)
.position(x: itemSize / 2.0 + floor(CGFloat(i % rowCount) * itemSize * (1.0 + defaultPaddingFraction)), y: i / rowCount == 0 ? firstRowY : secondRowY)
})
}) })
default: default:
return AnyView(ZStack { return AnyView(ZStack {
@@ -101,9 +124,7 @@ struct WidgetView: View {
var body: some View { var body: some View {
ZStack { ZStack {
Color(.systemBackground) Color(.systemBackground)
GeometryReader { geometry in peerViews()
peerViews(geometry: geometry)
}
} }
.padding(.all) .padding(.all)
} }
@@ -152,10 +173,10 @@ private let presentationData: WidgetPresentationData = {
} }
}() }()
let widgetData: WidgetData? = { func getWidgetData() -> PeersWidgetData {
let appBundleIdentifier = Bundle.main.bundleIdentifier! let appBundleIdentifier = Bundle.main.bundleIdentifier!
guard let lastDotRange = appBundleIdentifier.range(of: ".", options: [.backwards]) else { guard let lastDotRange = appBundleIdentifier.range(of: ".", options: [.backwards]) else {
return nil return .placeholder
} }
let baseAppBundleId = String(appBundleIdentifier[..<lastDotRange.lowerBound]) let baseAppBundleId = String(appBundleIdentifier[..<lastDotRange.lowerBound])
@@ -163,37 +184,34 @@ let widgetData: WidgetData? = {
let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName) let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName)
guard let appGroupUrl = maybeAppGroupUrl else { guard let appGroupUrl = maybeAppGroupUrl else {
return nil return .placeholder
} }
let rootPath = rootPathForBasePath(appGroupUrl.path) let rootPath = rootPathForBasePath(appGroupUrl.path)
if let data = try? Data(contentsOf: URL(fileURLWithPath: appLockStatePath(rootPath: rootPath))), let state = try? JSONDecoder().decode(LockState.self, from: data), isAppLocked(state: state) {
return .locked
}
let dataPath = rootPath + "/widget-data" let dataPath = rootPath + "/widget-data"
if let data = try? Data(contentsOf: URL(fileURLWithPath: dataPath)), let widgetData = try? JSONDecoder().decode(WidgetData.self, from: data) { if let data = try? Data(contentsOf: URL(fileURLWithPath: dataPath)), let widgetData = try? JSONDecoder().decode(WidgetData.self, from: data) {
return widgetData return .data(widgetData)
} else { } else {
return nil return .placeholder
} }
}() }
@main @main
struct Static_Widget: Widget { struct Static_Widget: Widget {
private let kind: String = "Static_Widget" private let kind: String = "Static_Widget"
public var body: some WidgetConfiguration { public var body: some WidgetConfiguration {
let data: PeersWidgetData
if let widgetData = widgetData {
data = .data(widgetData)
} else {
data = .placeholder
}
return StaticConfiguration( return StaticConfiguration(
kind: kind, kind: kind,
provider: Provider(), provider: Provider(),
content: { entry in content: { entry in
WidgetView(data: data) WidgetView(data: getWidgetData())
} }
) )
.supportedFamilies([.systemMedium]) .supportedFamilies([.systemMedium])

View File

@@ -59,6 +59,10 @@ final class WidgetDataContext {
} else { } else {
let _ = try? FileManager.default.removeItem(atPath: path) let _ = try? FileManager.default.removeItem(atPath: path)
} }
if #available(iOSApplicationExtension 14.0, iOS 14.0, *) {
WidgetCenter.shared.reloadAllTimelines()
}
}) })
self.widgetPresentationDataDisposable = (presentationData self.widgetPresentationDataDisposable = (presentationData