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 */
|
/* Begin PBXBuildFile section */
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
296251252AE7410D00D574FF /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296251242AE7410D00D574FF /* Colors.swift */; };
|
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 */; };
|
297F6FC72AD06E0D00FF159E /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 297F6FC62AD06E0D00FF159E /* WidgetKit.framework */; };
|
||||||
297F6FC92AD06E0D00FF159E /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 297F6FC82AD06E0D00FF159E /* SwiftUI.framework */; };
|
297F6FC92AD06E0D00FF159E /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 297F6FC82AD06E0D00FF159E /* SwiftUI.framework */; };
|
||||||
297F6FCC2AD06E0D00FF159E /* WonderousWidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 297F6FCB2AD06E0D00FF159E /* WonderousWidgetBundle.swift */; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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; };
|
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; };
|
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; };
|
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 */,
|
297FD5732AE18011008D8BFE /* WonderousWidgetView.swift */,
|
||||||
297FD5752AE19BD9008D8BFE /* WonderWidgetViewComponents.swift */,
|
297FD5752AE19BD9008D8BFE /* WonderWidgetViewComponents.swift */,
|
||||||
296251242AE7410D00D574FF /* Colors.swift */,
|
296251242AE7410D00D574FF /* Colors.swift */,
|
||||||
|
2978ECDC2B62D00C00E36CE8 /* FlutterAssets.swift */,
|
||||||
);
|
);
|
||||||
path = WonderousWidget;
|
path = WonderousWidget;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -451,6 +454,7 @@
|
|||||||
297FD5762AE19BD9008D8BFE /* WonderWidgetViewComponents.swift in Sources */,
|
297FD5762AE19BD9008D8BFE /* WonderWidgetViewComponents.swift in Sources */,
|
||||||
296251252AE7410D00D574FF /* Colors.swift in Sources */,
|
296251252AE7410D00D574FF /* Colors.swift in Sources */,
|
||||||
297F6FD32AD06E0F00FF159E /* WonderousWidget.intentdefinition in Sources */,
|
297F6FD32AD06E0F00FF159E /* WonderousWidget.intentdefinition in Sources */,
|
||||||
|
2978ECDD2B62D00C00E36CE8 /* FlutterAssets.swift in Sources */,
|
||||||
297FD5742AE18011008D8BFE /* WonderousWidgetView.swift in Sources */,
|
297FD5742AE18011008D8BFE /* WonderousWidgetView.swift in Sources */,
|
||||||
297F6FCE2AD06E0D00FF159E /* WonderousWidget.swift in Sources */,
|
297F6FCE2AD06E0D00FF159E /* WonderousWidget.swift in Sources */,
|
||||||
297F6FCC2AD06E0D00FF159E /* WonderousWidgetBundle.swift in Sources */,
|
297F6FCC2AD06E0D00FF159E /* WonderousWidgetBundle.swift in Sources */,
|
||||||
@ -640,14 +644,14 @@
|
|||||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_ENTITLEMENTS = "WonderousWidgetExtension.entitlements";
|
CODE_SIGN_ENTITLEMENTS = WonderousWidgetExtension.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = S3TL5AY6Y3;
|
DEVELOPMENT_TEAM = S3TL5AY6Y3;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "WonderousWidget/Info.plist";
|
INFOPLIST_FILE = WonderousWidget/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Wonderous Widget";
|
INFOPLIST_KEY_CFBundleDisplayName = "Wonderous Widget";
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
/// Define some custom extensions on the Color class, so we can use the shorthand syntax `..myColor`
|
||||||
extension Color {
|
extension Color {
|
||||||
public static let accent = Color(red: 0.89, green: 0.58, blue: 0.36)
|
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)
|
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?;
|
var uiImage:UIImage?;
|
||||||
// If there is no saved imageData, use the default bg image
|
// If there is no saved imageData, use the default bg image
|
||||||
if(entry.imageData.isEmpty){
|
if(entry.imageData.isEmpty){
|
||||||
let defaultImage = flutterAssetBundle.appending(path: "/assets/images/widget/background-empty.jpg").path();
|
uiImage = UIImage(contentsOfFile: FlutterImages.bgEmpty);
|
||||||
uiImage = UIImage(contentsOfFile: defaultImage);
|
|
||||||
}
|
}
|
||||||
// Load a base64 encoded image that has been written by the flutter app
|
// Load a base64 encoded image that has been written by the flutter app
|
||||||
else {
|
else {
|
||||||
uiImage = UIImage(data: Data(base64Encoded: entry.imageData)!)
|
uiImage = UIImage(data: Data(base64Encoded: entry.imageData)!)
|
||||||
}
|
}
|
||||||
if(uiImage != nil){
|
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
|
let image = GeometryReader { geometry in
|
||||||
Image(uiImage: uiImage!)
|
Image(uiImage: uiImage!)
|
||||||
.resizable()
|
.resizable()
|
||||||
@ -34,6 +33,7 @@ struct BgImage : View {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Declares a restyled version of the native ProgressView
|
||||||
struct GaugeProgressStyle: ProgressViewStyle {
|
struct GaugeProgressStyle: ProgressViewStyle {
|
||||||
func makeBody(configuration: Configuration) -> some View {
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
let fractionCompleted = configuration.fractionCompleted ?? 0
|
let fractionCompleted = configuration.fractionCompleted ?? 0
|
||||||
|
@ -2,19 +2,20 @@ import WidgetKit
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Intents
|
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 {
|
struct WonderousTimelineEntry : TimelineEntry {
|
||||||
|
// Date is a mandatory field for all TimelineEntries
|
||||||
let date: Date
|
let date: Date
|
||||||
|
// Custom field for the wonderous view
|
||||||
let discoveredCount:Int;
|
let discoveredCount:Int;
|
||||||
var title:String = "";
|
var title:String = "";
|
||||||
var subTitle:String = "";
|
var subTitle:String = "";
|
||||||
var imageData: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 {
|
struct WonderousWidget: Widget {
|
||||||
let kind: String = "WonderousWidget"
|
let kind: String = "WonderousWidget"
|
||||||
|
|
||||||
var body: some WidgetConfiguration {
|
var body: some WidgetConfiguration {
|
||||||
StaticConfiguration(kind: kind, provider: WonderousTimelineProvider()) { entry in
|
StaticConfiguration(kind: kind, provider: WonderousTimelineProvider()) { entry in
|
||||||
WonderousWidgetView(entry: entry)
|
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 {
|
struct WonderousTimelineProvider: TimelineProvider {
|
||||||
// Provide an entry for a placeholder version of the widget
|
// Provide an entry for a placeholder version of the widget
|
||||||
func placeholder(in context: Context) -> WonderousTimelineEntry {
|
func placeholder(in context: Context) -> WonderousTimelineEntry {
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
//
|
|
||||||
// WonderousWidgetBundle.swift
|
|
||||||
// Wonderous Widget
|
|
||||||
//
|
|
||||||
// Created by Shawn on 2023-10-06.
|
|
||||||
//
|
|
||||||
|
|
||||||
import WidgetKit
|
import WidgetKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
// WonderousWidgetBundle
|
||||||
|
// -> WonderousWidgetView
|
||||||
|
// -> WonderousWidgetViewComponents
|
||||||
@main
|
@main
|
||||||
struct WonderousWidgetBundle: WidgetBundle {
|
struct WonderousWidgetBundle: WidgetBundle {
|
||||||
var body: some Widget {
|
var body: some Widget {
|
||||||
|
@ -2,7 +2,7 @@ import WidgetKit
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Intents
|
import Intents
|
||||||
|
|
||||||
// Defines the view / layout of the widget
|
/// Defines the view / layout of the widget
|
||||||
struct WonderousWidgetView : View {
|
struct WonderousWidgetView : View {
|
||||||
@Environment(\.widgetFamily) var family: WidgetFamily
|
@Environment(\.widgetFamily) var family: WidgetFamily
|
||||||
var entry: WonderousTimelineProvider.Entry
|
var entry: WonderousTimelineProvider.Entry
|
||||||
@ -10,14 +10,13 @@ struct WonderousWidgetView : View {
|
|||||||
let showTitle = family == .systemLarge
|
let showTitle = family == .systemLarge
|
||||||
let showIcon = family != .systemSmall
|
let showIcon = family != .systemSmall
|
||||||
let showTitleAndDesc = family != .systemSmall
|
let showTitleAndDesc = family != .systemSmall
|
||||||
|
let progressPct = Double(entry.discoveredCount) / 24.0
|
||||||
let progress = Double(entry.discoveredCount) / 24.0
|
let iconImage = FlutterImages.icon;
|
||||||
let iconImage = flutterAssetBundle.appending(
|
|
||||||
path: "/assets/images/widget/wonderous-icon.png"
|
|
||||||
).path()
|
|
||||||
let title = entry.title.isEmpty ? "Wonderous" : entry.title;
|
let title = entry.title.isEmpty ? "Wonderous" : entry.title;
|
||||||
let subTitle = entry.subTitle.isEmpty ? "Search for hidden artifacts" : entry.subTitle;
|
let subTitle = entry.subTitle.isEmpty ? "Search for hidden artifacts" : entry.subTitle;
|
||||||
|
|
||||||
let content = VStack{
|
let content = VStack{
|
||||||
|
// Top row with optional Title and Icon
|
||||||
HStack {
|
HStack {
|
||||||
if(showTitle) {
|
if(showTitle) {
|
||||||
Text("Collection")
|
Text("Collection")
|
||||||
@ -32,7 +31,10 @@ struct WonderousWidgetView : View {
|
|||||||
.frame(height: 24)
|
.frame(height: 24)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer();
|
Spacer();
|
||||||
|
|
||||||
|
// Bottom hz row with title, desc and progress gauge
|
||||||
HStack {
|
HStack {
|
||||||
if(showTitleAndDesc) {
|
if(showTitleAndDesc) {
|
||||||
VStack(alignment: .leading){
|
VStack(alignment: .leading){
|
||||||
@ -46,14 +48,16 @@ struct WonderousWidgetView : View {
|
|||||||
}
|
}
|
||||||
Spacer();
|
Spacer();
|
||||||
ZStack{
|
ZStack{
|
||||||
ProgressView(value: progress)
|
ProgressView(value: progressPct)
|
||||||
.progressViewStyle(GaugeProgressStyle())
|
.progressViewStyle(GaugeProgressStyle())
|
||||||
.frame(width: 48, height: 48)
|
.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{
|
return ZStack{
|
||||||
BgImage(entry: entry).opacity(0.8)
|
BgImage(entry: entry).opacity(0.8)
|
||||||
LinearGradient(
|
LinearGradient(
|
||||||
@ -62,21 +66,11 @@ struct WonderousWidgetView : View {
|
|||||||
endPoint: .bottom)
|
endPoint: .bottom)
|
||||||
content.padding(16)
|
content.padding(16)
|
||||||
}
|
}
|
||||||
|
// Ios requires that widgets have a background color
|
||||||
.widgetBackground(Color.darkGrey)
|
.widgetBackground(Color.darkGrey)
|
||||||
|
// Deeplink into collections view when tapped
|
||||||
.widgetURL(URL(string: "wonderous:///home/collection"))
|
.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) {
|
Widget _buildProgressRow(BuildContext context) {
|
||||||
|
int percent = (count / total * 100).round();
|
||||||
return Row(children: [
|
return Row(children: [
|
||||||
Text(
|
Text(
|
||||||
$strings.collectionLabelDiscovered((count / total * 100).round()),
|
$strings.collectionLabelDiscovered(percent),
|
||||||
style: $styles.text.body.copyWith(color: $styles.colors.accent1),
|
style: $styles.text.body.copyWith(color: $styles.colors.accent1),
|
||||||
),
|
),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: wonders
|
name: wonders
|
||||||
description: Explore the famous wonders of the world.
|
description: Explore the famous wonders of the world.
|
||||||
publish_to: "none"
|
publish_to: "none"
|
||||||
version: 2.2.0
|
version: 2.2.1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.0 <3.0.0"
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user