diff --git a/android/app/src/main/kotlin/com/fahrecker/time_progress_tracker/MainActivity.kt b/android/app/src/main/kotlin/com/fahrecker/time_progress_tracker/MainActivity.kt new file mode 100644 index 0000000..f8d43b9 --- /dev/null +++ b/android/app/src/main/kotlin/com/fahrecker/time_progress_tracker/MainActivity.kt @@ -0,0 +1,6 @@ +package com.fahrecker.time_progress_tracker + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..449a9f9 --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f7..9367d48 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) + en CFBundleExecutable App CFBundleIdentifier diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index e8efba1..ec97fc6 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 399e934..3648d51 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1,2 +1,3 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile index f7d6a5e..252d9ec 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '9.0' +platform :ios, '9.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' @@ -28,6 +28,9 @@ require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelpe flutter_ios_podfile_setup target 'Runner' do + use_frameworks! + use_modular_headers! + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index b354908..726c80b 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,15 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 4D431DF94830EB4E4109ECB2 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A0182DC80C66D064A11FDF0B /* libPods-Runner.a */; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 6186AFFAE7FCA76C81CF360E /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D5EAE1ADE1FFBE7D23EE84E /* Pods_Runner.framework */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; @@ -33,22 +32,21 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 37CBB71D7FE5A5197D6A6BF7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 1DBA7F16BF734A3CE98E5546 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 7D5EAE1ADE1FFBE7D23EE84E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - A0182DC80C66D064A11FDF0B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - F9B8D838B24E4D784CD9D717 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - FF252FCCD702699EBF6FC287 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + B4DFA246891E5346CCC8628F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + DC45E65269FD602449E1FEBD /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -56,19 +54,21 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 4D431DF94830EB4E4109ECB2 /* libPods-Runner.a in Frameworks */, + 6186AFFAE7FCA76C81CF360E /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 79DE0847F7F4B7CF08AEE47D /* Frameworks */ = { + 7425B1E33E3BCBE464E2CBB5 /* Pods */ = { isa = PBXGroup; children = ( - A0182DC80C66D064A11FDF0B /* libPods-Runner.a */, + B4DFA246891E5346CCC8628F /* Pods-Runner.debug.xcconfig */, + 1DBA7F16BF734A3CE98E5546 /* Pods-Runner.release.xcconfig */, + DC45E65269FD602449E1FEBD /* Pods-Runner.profile.xcconfig */, ); - name = Frameworks; + path = Pods; sourceTree = ""; }; 9740EEB11CF90186004384FC /* Flutter */ = { @@ -88,8 +88,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - 9DBFAAD22EAE0F654D097AD5 /* Pods */, - 79DE0847F7F4B7CF08AEE47D /* Frameworks */, + 7425B1E33E3BCBE464E2CBB5 /* Pods */, + E3A24E042363B3BCA7910470 /* Frameworks */, ); sourceTree = ""; }; @@ -104,35 +104,24 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, ); path = Runner; sourceTree = ""; }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { + E3A24E042363B3BCA7910470 /* Frameworks */ = { isa = PBXGroup; children = ( - 97C146F21CF9000F007C117D /* main.m */, + 7D5EAE1ADE1FFBE7D23EE84E /* Pods_Runner.framework */, ); - name = "Supporting Files"; - sourceTree = ""; - }; - 9DBFAAD22EAE0F654D097AD5 /* Pods */ = { - isa = PBXGroup; - children = ( - 37CBB71D7FE5A5197D6A6BF7 /* Pods-Runner.debug.xcconfig */, - FF252FCCD702699EBF6FC287 /* Pods-Runner.release.xcconfig */, - F9B8D838B24E4D784CD9D717 /* Pods-Runner.profile.xcconfig */, - ); - path = Pods; + name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ @@ -142,13 +131,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - B3E7CCA0AF60658FE8F4BF7D /* [CP] Check Pods Manifest.lock */, + A60954191C254DCAC69F1735 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 555CAADD55712EED12802136 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -170,6 +160,7 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; }; }; }; @@ -220,6 +211,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 555CAADD55712EED12802136 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -234,7 +242,7 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - B3E7CCA0AF60658FE8F4BF7D /* [CP] Check Pods Manifest.lock */ = { + A60954191C254DCAC69F1735 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -263,8 +271,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -332,7 +339,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -346,23 +353,19 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = RD9K843SK5; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.fahrecker.timeProgressCalculator; + PRODUCT_BUNDLE_IDENTIFIER = com.fahrecker.timeProgressTracker; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; @@ -414,7 +417,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -463,10 +466,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -477,23 +482,20 @@ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = RD9K843SK5; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.fahrecker.timeProgressCalculator; + PRODUCT_BUNDLE_IDENTIFIER = com.fahrecker.timeProgressTracker; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -503,23 +505,19 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = RD9K843SK5; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.fahrecker.timeProgressCalculator; + PRODUCT_BUNDLE_IDENTIFIER = com.fahrecker.timeProgressTracker; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; @@ -550,4 +548,4 @@ /* End XCConfigurationList section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; -} \ No newline at end of file +} diff --git a/ios/Runner/AppDelegate.h b/ios/Runner/AppDelegate.h deleted file mode 100644 index 36e21bb..0000000 --- a/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/ios/Runner/AppDelegate.m b/ios/Runner/AppDelegate.m deleted file mode 100644 index 70e8393..0000000 --- a/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,13 +0,0 @@ -#import "AppDelegate.h" -#import "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 230bb10..22ba1a4 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - time_progress_calculator + time_progress_tracker CFBundlePackageType APPL CFBundleShortVersionString diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/ios/Runner/main.m b/ios/Runner/main.m deleted file mode 100644 index dff6597..0000000 --- a/ios/Runner/main.m +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/lib/models/app_exceptions.dart b/lib/models/app_exceptions.dart index c37d421..dedc93d 100644 --- a/lib/models/app_exceptions.dart +++ b/lib/models/app_exceptions.dart @@ -14,5 +14,18 @@ class TimeProgressStartTimeIsNotBeforeEndTimeException implements Exception { this.startTime, this.endTime); String errMsg() => - "The Start Time has to be before the end time. Therefore these values are invalid: Start Time: $startTime EndTime: $endTime"; + "The Start Time has to be before the end time. Therefore these values are" + " invalid: Start Time: $startTime EndTime: $endTime"; +} + +class TimeProgressHasStartedException implements Exception { + String errMsg() => + "This TimeProgress has started. Therefore all calculation, which assume, " + "that the progress hasn't started yet can't be performed"; +} + +class TimeProgressHasNotEndedException implements Exception { + String errMsg() => + "This TimeProgress hasn't ended. Therefore all calculation, which assume," + " that the progress has ended already can't be performed"; } diff --git a/lib/models/time_progress.dart b/lib/models/time_progress.dart index ef758e8..dde845d 100644 --- a/lib/models/time_progress.dart +++ b/lib/models/time_progress.dart @@ -47,9 +47,19 @@ class TimeProgress { bool hasStarted() => DateTime.now().millisecondsSinceEpoch > startTime.millisecondsSinceEpoch; + int daysTillStart() { + if (hasStarted()) throw new TimeProgressHasStartedException(); + return startTime.difference(DateTime.now()).inDays; + } + bool hasEnded() => DateTime.now().millisecondsSinceEpoch > endTime.millisecondsSinceEpoch; + int daysSinceEnd() { + if (!hasEnded()) throw new TimeProgressHasNotEndedException(); + return DateTime.now().difference(endTime).inDays; + } + @override int get hashCode => id.hashCode ^ name.hashCode ^ startTime.hashCode ^ endTime.hashCode; diff --git a/lib/widgets/home/home_progress_list_tile.dart b/lib/widgets/home/home_progress_list_tile.dart index b62f3b5..be8b8d7 100644 --- a/lib/widgets/home/home_progress_list_tile.dart +++ b/lib/widgets/home/home_progress_list_tile.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:percent_indicator/linear_percent_indicator.dart'; import 'package:time_progress_tracker/models/time_progress.dart'; -import 'package:time_progress_tracker/screens/progress_detail_screen.dart'; +import 'package:time_progress_tracker/widgets/progress_list_view/progress_list_tile.dart'; class HomeProgressListTile extends StatelessWidget { final TimeProgress timeProgress; @@ -16,33 +15,11 @@ class HomeProgressListTile extends StatelessWidget { @override Widget build(BuildContext context) { - Widget listTileSubTitle; - if (timeProgress.hasStarted() && !timeProgress.hasEnded()) - listTileSubTitle = LinearPercentIndicator( - center: Text( - "${(timeProgress.percentDone() * 100).floor()} %", - style: TextStyle(color: Colors.white), - ), - percent: timeProgress.percentDone(), - progressColor: doneColor, - backgroundColor: leftColor, - lineHeight: 20, - ); - if (!timeProgress.hasStarted()) - listTileSubTitle = Text( - "Starts in ${timeProgress.startTime.difference(DateTime.now()).inDays} Days"); - if (timeProgress.hasEnded()) - listTileSubTitle = Text( - "Ended ${DateTime.now().difference(timeProgress.endTime).inDays} Days ago."); - return Card( - child: ListTile( - title: Text(timeProgress.name), - subtitle: listTileSubTitle, - onTap: () { - Navigator.pushNamed(context, ProgressDetailScreen.routeName, - arguments: ProgressDetailScreenArguments(timeProgress.id)); - }, + child: ProgressListTile( + timeProgress: timeProgress, + doneColor: doneColor, + leftColor: leftColor, ), ); } diff --git a/lib/widgets/progress_list_view/progress_list_tile.dart b/lib/widgets/progress_list_view/progress_list_tile.dart new file mode 100644 index 0000000..4a2e152 --- /dev/null +++ b/lib/widgets/progress_list_view/progress_list_tile.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:time_progress_tracker/models/time_progress.dart'; + +class ProgressListTileStrings { + static String percentString(TimeProgress tp) => + "${(tp.percentDone() * 100).floorToDouble()} %"; + + static String startsInDaysString(TimeProgress tp) => + "Starts in ${tp.daysTillStart()} Days."; + + static String endedDaysAgoString(TimeProgress tp) => + "Ended ${tp.daysSinceEnd()} Days ago."; +} + +class ProgressListTile extends StatelessWidget { + final TimeProgress timeProgress; + final Color doneColor, leftColor; + + ProgressListTile({ + @required this.timeProgress, + @required this.doneColor, + @required this.leftColor, + }); + + Widget _renderSubtitle(BuildContext context) { + if (!timeProgress.hasStarted()) + return Text(ProgressListTileStrings.startsInDaysString(timeProgress)); + if (timeProgress.hasEnded()) + return Text(ProgressListTileStrings.endedDaysAgoString(timeProgress)); + return LinearPercentIndicator( + center: Text(ProgressListTileStrings.percentString(timeProgress)), + percent: timeProgress.percentDone(), + progressColor: doneColor, + backgroundColor: leftColor, + lineHeight: 20, + ); + } + + @override + Widget build(BuildContext context) { + return ListTile( + title: Text(timeProgress.name), + subtitle: _renderSubtitle(context), + ); + } +} diff --git a/lib/widgets/progress_list_view/progress_list_view.dart b/lib/widgets/progress_list_view/progress_list_view.dart new file mode 100644 index 0000000..2165a84 --- /dev/null +++ b/lib/widgets/progress_list_view/progress_list_view.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:time_progress_tracker/models/time_progress.dart'; +import 'package:time_progress_tracker/widgets/progress_list_view/progress_list_tile.dart'; + +class ProgressListView extends StatelessWidget { + final List timeProgressList; + final Color doneColor, leftColor; + + ProgressListView({ + @required this.timeProgressList, + @required this.doneColor, + @required this.leftColor, + }); + + List _renderListViewChildren() { + return timeProgressList.map((e) => + Card( + child: ProgressListTile( + timeProgress: e, + doneColor: doneColor, + leftColor: leftColor, + ), + ) + ).toList(growable: false); + } + + @override + Widget build(BuildContext context) { + return ListView( + children: _renderListViewChildren(), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 6e3f677..742df77 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -172,13 +172,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" - package_info: - dependency: "direct main" - description: - name: package_info - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" path: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 51d9030..df5abd4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,7 +28,6 @@ dependencies: flutter_picker: git: git://github.com/yangyxd/flutter_picker.git meta: - package_info: percent_indicator: redux: shared_preferences: diff --git a/test/MaterialTesterWidget.dart b/test/MaterialTesterWidget.dart new file mode 100644 index 0000000..7fc20fc --- /dev/null +++ b/test/MaterialTesterWidget.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +class MaterialTesterWidget extends StatelessWidget { + final Widget widget; + + MaterialTesterWidget({ + @required this.widget, + }); + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: widget, + ), + ); + } +} diff --git a/test/widget_test.dart b/test/widget_test.dart index b843dca..e95f9a7 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -7,24 +7,124 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; +import 'package:time_progress_tracker/models/app_settings.dart'; +import 'package:time_progress_tracker/models/time_progress.dart'; +import 'package:time_progress_tracker/widgets/progress_list_view/progress_list_tile.dart'; +import 'package:time_progress_tracker/widgets/progress_list_view/progress_list_view.dart'; -import 'package:time_progress_calculator/main.dart'; +import 'MaterialTesterWidget.dart'; void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); + final AppSettings _defaultAppSettings = AppSettings.defaults(); + final int _thisYear = DateTime.now().year; + final TimeProgress _activeProgress = TimeProgress( + "TestProgress", DateTime(_thisYear - 2), DateTime(_thisYear + 2)); - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); + void _findStringOnce(String str) => expect(find.text(str), findsOneWidget); - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); + testWidgets("Progress List Tile with currently active progress works", + (WidgetTester tester) async { + await tester.pumpWidget(MaterialTesterWidget( + widget: ProgressListTile( + timeProgress: _activeProgress, + doneColor: _defaultAppSettings.doneColor, + leftColor: _defaultAppSettings.leftColor, + ), + )); - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); + _findStringOnce(_activeProgress.name); + _findStringOnce(ProgressListTileStrings.percentString(_activeProgress)); + + WidgetPredicate linearPercentPredicate = (Widget widget) => + widget is LinearPercentIndicator && + widget.percent == _activeProgress.percentDone() && + widget.progressColor == _defaultAppSettings.doneColor && + widget.backgroundColor == _defaultAppSettings.leftColor; + expect(find.byWidgetPredicate(linearPercentPredicate), findsOneWidget); + }); + + testWidgets("Progress List Tile with future progress works", + (WidgetTester tester) async { + TimeProgress futureProgress = TimeProgress( + "Test Progress", + DateTime(_thisYear + 1), + DateTime(_thisYear + 2), + ); + + await tester.pumpWidget(MaterialTesterWidget( + widget: ProgressListTile( + timeProgress: futureProgress, + doneColor: _defaultAppSettings.doneColor, + leftColor: _defaultAppSettings.leftColor, + ), + )); + + _findStringOnce(futureProgress.name); + _findStringOnce(ProgressListTileStrings.startsInDaysString(futureProgress)); + }); + + testWidgets("Progress List Tile with past progress works", + (WidgetTester tester) async { + TimeProgress pastProgress = TimeProgress( + "Test Progress", + DateTime(_thisYear - 2), + DateTime(_thisYear - 1), + ); + + await tester.pumpWidget(MaterialTesterWidget( + widget: ProgressListTile( + timeProgress: pastProgress, + doneColor: _defaultAppSettings.doneColor, + leftColor: _defaultAppSettings.leftColor, + ), + )); + + _findStringOnce(pastProgress.name); + _findStringOnce(ProgressListTileStrings.endedDaysAgoString(pastProgress)); + }); + + WidgetPredicate getProgressListTilePredicate( + TimeProgress tp, AppSettings as) => + (Widget widget) => + widget is ProgressListTile && + widget.timeProgress == tp && + widget.doneColor == as.doneColor && + widget.leftColor == as.leftColor; + + testWidgets("Progress List View displays one tile", + (WidgetTester tester) async { + await tester.pumpWidget(MaterialTesterWidget( + widget: ProgressListView( + timeProgressList: [_activeProgress], + doneColor: _defaultAppSettings.doneColor, + leftColor: _defaultAppSettings.leftColor, + ), + )); + + _findStringOnce(_activeProgress.name); + expect( + find.byWidgetPredicate( + getProgressListTilePredicate(_activeProgress, _defaultAppSettings)), + findsOneWidget); + }); + + testWidgets("Progress List View displays file tiles", + (WidgetTester tester) async { + List tpList = []; + for (int i = 0; i < 5; i++) tpList.add(_activeProgress); + await tester.pumpWidget(MaterialTesterWidget( + widget: ProgressListView( + timeProgressList: tpList, + doneColor: _defaultAppSettings.doneColor, + leftColor: _defaultAppSettings.leftColor, + ), + )); + + expect(find.text(_activeProgress.name), findsNWidgets(5)); + expect( + find.byWidgetPredicate( + getProgressListTilePredicate(_activeProgress, _defaultAppSettings)), + findsNWidgets(5)); }); } diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/web/favicon.png differ diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/web/icons/Icon-192.png differ diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/web/icons/Icon-512.png differ diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..f7cd0cd --- /dev/null +++ b/web/index.html @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + time_progress_tracker + + + + + + + + diff --git a/web/manifest.json b/web/manifest.json new file mode 100644 index 0000000..66c48a7 --- /dev/null +++ b/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "time_progress_tracker", + "short_name": "time_progress_tracker", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +}