Cleanup home_widget views, add comments, fix rounding issue
This commit is contained in:
parent
45a9a8348f
commit
8d5daf3edd
@ -9,6 +9,7 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
296251252AE7410D00D574FF /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296251242AE7410D00D574FF /* Colors.swift */; };
|
||||
2978ECDD2B62D00C00E36CE8 /* FlutterAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2978ECDC2B62D00C00E36CE8 /* FlutterAssets.swift */; };
|
||||
297F6FC72AD06E0D00FF159E /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 297F6FC62AD06E0D00FF159E /* WidgetKit.framework */; };
|
||||
297F6FC92AD06E0D00FF159E /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 297F6FC82AD06E0D00FF159E /* SwiftUI.framework */; };
|
||||
297F6FCC2AD06E0D00FF159E /* WonderousWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297F6FCB2AD06E0D00FF159E /* WonderousWidgetBundle.swift */; };
|
||||
@ -73,6 +74,7 @@
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
296251242AE7410D00D574FF /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
|
||||
2978ECDC2B62D00C00E36CE8 /* FlutterAssets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlutterAssets.swift; sourceTree = "<group>"; };
|
||||
297F6FC52AD06E0D00FF159E /* Wonderous WidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; name = "Wonderous WidgetExtension.appex"; path = WonderousWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
297F6FC62AD06E0D00FF159E /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
||||
297F6FC82AD06E0D00FF159E /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
||||
@ -141,6 +143,7 @@
|
||||
297FD5732AE18011008D8BFE /* WonderousWidgetView.swift */,
|
||||
297FD5752AE19BD9008D8BFE /* WonderWidgetViewComponents.swift */,
|
||||
296251242AE7410D00D574FF /* Colors.swift */,
|
||||
2978ECDC2B62D00C00E36CE8 /* FlutterAssets.swift */,
|
||||
);
|
||||
path = WonderousWidget;
|
||||
sourceTree = "<group>";
|
||||
@ -451,6 +454,7 @@
|
||||
297FD5762AE19BD9008D8BFE /* WonderWidgetViewComponents.swift in Sources */,
|
||||
296251252AE7410D00D574FF /* Colors.swift in Sources */,
|
||||
297F6FD32AD06E0F00FF159E /* WonderousWidget.intentdefinition in Sources */,
|
||||
2978ECDD2B62D00C00E36CE8 /* FlutterAssets.swift in Sources */,
|
||||
297FD5742AE18011008D8BFE /* WonderousWidgetView.swift in Sources */,
|
||||
297F6FCE2AD06E0D00FF159E /* WonderousWidget.swift in Sources */,
|
||||
297F6FCC2AD06E0D00FF159E /* WonderousWidgetBundle.swift in Sources */,
|
||||
@ -640,14 +644,14 @@
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "WonderousWidgetExtension.entitlements";
|
||||
CODE_SIGN_ENTITLEMENTS = WonderousWidgetExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = S3TL5AY6Y3;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "WonderousWidget/Info.plist";
|
||||
INFOPLIST_FILE = WonderousWidget/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Wonderous Widget";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
/// Define some custom extensions on the Color class, so we can use the shorthand syntax `..myColor`
|
||||
extension Color {
|
||||
public static let accent = Color(red: 0.89, green: 0.58, blue: 0.36)
|
||||
public static let offWhite = Color(red: 0.97, green: 0.92, blue: 0.9)
|
||||
|
22
ios/WonderousWidget/FlutterAssets.swift
Normal file
22
ios/WonderousWidget/FlutterAssets.swift
Normal file
@ -0,0 +1,22 @@
|
||||
import Foundation
|
||||
|
||||
struct FlutterImages {
|
||||
static let bgEmpty = getAssetPath("/assets/images/widget/background-empty.jpg")
|
||||
static let icon = getAssetPath("/assets/images/widget/wonderous-icon.png")
|
||||
}
|
||||
|
||||
func getAssetPath(_ path : String) -> String {
|
||||
return assetBundleUrl.appending(path: path).path()
|
||||
}
|
||||
|
||||
// Returns a file path to the location of the flutter assetBundle
|
||||
var assetBundleUrl: URL {
|
||||
let bundle = Bundle.main
|
||||
if bundle.bundleURL.pathExtension == "appex" {
|
||||
// Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex
|
||||
var url = bundle.bundleURL.deletingLastPathComponent().deletingLastPathComponent()
|
||||
url.append(component: "Frameworks/App.framework/flutter_assets")
|
||||
return url
|
||||
}
|
||||
return bundle.bundleURL
|
||||
}
|
@ -10,15 +10,14 @@ struct BgImage : View {
|
||||
var uiImage:UIImage?;
|
||||
// If there is no saved imageData, use the default bg image
|
||||
if(entry.imageData.isEmpty){
|
||||
let defaultImage = flutterAssetBundle.appending(path: "/assets/images/widget/background-empty.jpg").path();
|
||||
uiImage = UIImage(contentsOfFile: defaultImage);
|
||||
uiImage = UIImage(contentsOfFile: FlutterImages.bgEmpty);
|
||||
}
|
||||
// Load a base64 encoded image that has been written by the flutter app
|
||||
else {
|
||||
uiImage = UIImage(data: Data(base64Encoded: entry.imageData)!)
|
||||
}
|
||||
if(uiImage != nil){
|
||||
// Use geometry reader to prevent the image from pushing the other content out of the widgets bounds (https://stackoverflow.com/questions/57593552/swiftui-prevent-image-from-expanding-view-rect-outside-of-screen-bounds)
|
||||
// Use geometry reader to prevent an oversized bg image from pushing the other content out of the widgets bounds (https://stackoverflow.com/questions/57593552/swiftui-prevent-image-from-expanding-view-rect-outside-of-screen-bounds)
|
||||
let image = GeometryReader { geometry in
|
||||
Image(uiImage: uiImage!)
|
||||
.resizable()
|
||||
@ -34,6 +33,7 @@ struct BgImage : View {
|
||||
|
||||
}
|
||||
|
||||
// Declares a restyled version of the native ProgressView
|
||||
struct GaugeProgressStyle: ProgressViewStyle {
|
||||
func makeBody(configuration: Configuration) -> some View {
|
||||
let fractionCompleted = configuration.fractionCompleted ?? 0
|
||||
|
@ -2,19 +2,20 @@ import WidgetKit
|
||||
import SwiftUI
|
||||
import Intents
|
||||
|
||||
/// Entry, is passed into the view and defines the data it needs
|
||||
/// Every home-widget requires a TimelineEntry. This is passed into the view and propvides any data it needs
|
||||
struct WonderousTimelineEntry : TimelineEntry {
|
||||
// Date is a mandatory field for all TimelineEntries
|
||||
let date: Date
|
||||
// Custom field for the wonderous view
|
||||
let discoveredCount:Int;
|
||||
var title:String = "";
|
||||
var subTitle:String = "";
|
||||
var imageData:String = "";
|
||||
}
|
||||
|
||||
// Widget, defines the display name and description and also declared the main View
|
||||
/// Widget, defines some high level configuration options as well as the primary view that will display the widget.
|
||||
struct WonderousWidget: Widget {
|
||||
let kind: String = "WonderousWidget"
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
StaticConfiguration(kind: kind, provider: WonderousTimelineProvider()) { entry in
|
||||
WonderousWidgetView(entry: entry)
|
||||
@ -26,7 +27,12 @@ struct WonderousWidget: Widget {
|
||||
}
|
||||
}
|
||||
|
||||
// Provider,returns various WonderousEntry configs based on current context
|
||||
struct WonderousConfig {
|
||||
let iosKey = "group.com.gskinner.flutter.wonders.widget"
|
||||
let discoveredCountKey = "dicoveredCount"
|
||||
}
|
||||
|
||||
/// TimelineProvider, returns various WonderousTimelineEntry configurations for different contexts
|
||||
struct WonderousTimelineProvider: TimelineProvider {
|
||||
// Provide an entry for a placeholder version of the widget
|
||||
func placeholder(in context: Context) -> WonderousTimelineEntry {
|
||||
|
@ -1,13 +1,9 @@
|
||||
//
|
||||
// WonderousWidgetBundle.swift
|
||||
// Wonderous Widget
|
||||
//
|
||||
// Created by Shawn on 2023-10-06.
|
||||
//
|
||||
|
||||
import WidgetKit
|
||||
import SwiftUI
|
||||
|
||||
// WonderousWidgetBundle
|
||||
// -> WonderousWidgetView
|
||||
// -> WonderousWidgetViewComponents
|
||||
@main
|
||||
struct WonderousWidgetBundle: WidgetBundle {
|
||||
var body: some Widget {
|
||||
|
@ -2,7 +2,7 @@ import WidgetKit
|
||||
import SwiftUI
|
||||
import Intents
|
||||
|
||||
// Defines the view / layout of the widget
|
||||
/// Defines the view / layout of the widget
|
||||
struct WonderousWidgetView : View {
|
||||
@Environment(\.widgetFamily) var family: WidgetFamily
|
||||
var entry: WonderousTimelineProvider.Entry
|
||||
@ -10,14 +10,13 @@ struct WonderousWidgetView : View {
|
||||
let showTitle = family == .systemLarge
|
||||
let showIcon = family != .systemSmall
|
||||
let showTitleAndDesc = family != .systemSmall
|
||||
|
||||
let progress = Double(entry.discoveredCount) / 24.0
|
||||
let iconImage = flutterAssetBundle.appending(
|
||||
path: "/assets/images/widget/wonderous-icon.png"
|
||||
).path()
|
||||
let progressPct = Double(entry.discoveredCount) / 24.0
|
||||
let iconImage = FlutterImages.icon;
|
||||
let title = entry.title.isEmpty ? "Wonderous" : entry.title;
|
||||
let subTitle = entry.subTitle.isEmpty ? "Search for hidden artifacts" : entry.subTitle;
|
||||
|
||||
let content = VStack{
|
||||
// Top row with optional Title and Icon
|
||||
HStack {
|
||||
if(showTitle) {
|
||||
Text("Collection")
|
||||
@ -32,7 +31,10 @@ struct WonderousWidgetView : View {
|
||||
.frame(height: 24)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer();
|
||||
|
||||
// Bottom hz row with title, desc and progress gauge
|
||||
HStack {
|
||||
if(showTitleAndDesc) {
|
||||
VStack(alignment: .leading){
|
||||
@ -46,14 +48,16 @@ struct WonderousWidgetView : View {
|
||||
}
|
||||
Spacer();
|
||||
ZStack{
|
||||
ProgressView(value: progress)
|
||||
ProgressView(value: progressPct)
|
||||
.progressViewStyle(GaugeProgressStyle())
|
||||
.frame(width: 48, height: 48)
|
||||
Text("\(Int(progress * 100))%").font(.system(size: 13)).foregroundColor(.white)
|
||||
|
||||
Text("\(Int((progressPct * 100).rounded()))%").font(.system(size: 13)).foregroundColor(.white)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stack content on top of the background image and a gradient
|
||||
return ZStack{
|
||||
BgImage(entry: entry).opacity(0.8)
|
||||
LinearGradient(
|
||||
@ -62,21 +66,11 @@ struct WonderousWidgetView : View {
|
||||
endPoint: .bottom)
|
||||
content.padding(16)
|
||||
}
|
||||
// Ios requires that widgets have a background color
|
||||
.widgetBackground(Color.darkGrey)
|
||||
// Deeplink into collections view when tapped
|
||||
.widgetURL(URL(string: "wonderous:///home/collection"))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: Refactor to getFlutterAsset(String path), include /assets, or maybe just getFlutterImage(String path), include assets/images
|
||||
// Returns a file path to the location of the flutter assetBundle
|
||||
var flutterAssetBundle: URL {
|
||||
let bundle = Bundle.main
|
||||
if bundle.bundleURL.pathExtension == "appex" {
|
||||
// Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex
|
||||
var url = bundle.bundleURL.deletingLastPathComponent().deletingLastPathComponent()
|
||||
url.append(component: "Frameworks/App.framework/flutter_assets")
|
||||
return url
|
||||
}
|
||||
return bundle.bundleURL
|
||||
}
|
||||
|
@ -42,9 +42,10 @@ class _CollectionFooter extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildProgressRow(BuildContext context) {
|
||||
int percent = (count / total * 100).round();
|
||||
return Row(children: [
|
||||
Text(
|
||||
$strings.collectionLabelDiscovered((count / total * 100).round()),
|
||||
$strings.collectionLabelDiscovered(percent),
|
||||
style: $styles.text.body.copyWith(color: $styles.colors.accent1),
|
||||
),
|
||||
Spacer(),
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: wonders
|
||||
description: Explore the famous wonders of the world.
|
||||
publish_to: "none"
|
||||
version: 2.2.0
|
||||
version: 2.2.1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.17.0 <3.0.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user