diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..bad9d0d2 Binary files /dev/null and b/.DS_Store differ diff --git a/assets/.DS_Store b/assets/.DS_Store new file mode 100644 index 00000000..2f718152 Binary files /dev/null and b/assets/.DS_Store differ diff --git a/ios/.DS_Store b/ios/.DS_Store new file mode 100644 index 00000000..8baff32f Binary files /dev/null and b/ios/.DS_Store differ diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index f2872cf4..8c6e5614 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 12.0 diff --git a/ios/Podfile b/ios/Podfile index d97f17e2..279576f3 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -32,9 +32,6 @@ target 'Runner' do use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end end post_install do |installer| diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 36428fd8..29940b0f 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,12 +3,13 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; 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 */; }; + 68F4DD6659288F4CFDC41C5C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7024DE075B2C1E5A149230E4 /* 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 */; }; @@ -31,7 +32,10 @@ /* 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 = ""; }; + 1DC098B20AE17A152A9E7BC6 /* 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 = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 4B6A3CFB60775CA626789750 /* 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 = ""; }; + 7024DE075B2C1E5A149230E4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = ""; }; @@ -42,6 +46,7 @@ 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 = ""; }; + EC46FEE88A2E87A3510B5EC3 /* 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 */ @@ -49,12 +54,31 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 68F4DD6659288F4CFDC41C5C /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 28430AE518366E9EB19A31C9 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7024DE075B2C1E5A149230E4 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 6F201E010624CF963CC3A17B /* Pods */ = { + isa = PBXGroup; + children = ( + 1DC098B20AE17A152A9E7BC6 /* Pods-Runner.debug.xcconfig */, + 4B6A3CFB60775CA626789750 /* Pods-Runner.release.xcconfig */, + EC46FEE88A2E87A3510B5EC3 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -72,6 +96,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, + 6F201E010624CF963CC3A17B /* Pods */, + 28430AE518366E9EB19A31C9 /* Frameworks */, ); sourceTree = ""; }; @@ -105,12 +131,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + C9531164650CD277994F87F5 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 8944C2327F94FA34E28A19A3 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -127,7 +155,8 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -171,10 +200,12 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -183,8 +214,26 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 8944C2327F94FA34E28A19A3 /* [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; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -197,6 +246,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + C9531164650CD277994F87F5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -235,6 +306,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -254,6 +326,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -264,6 +337,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -272,7 +346,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -288,13 +362,17 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -311,6 +389,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -330,6 +409,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -340,6 +420,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -354,7 +435,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -366,6 +447,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -385,6 +467,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -395,6 +478,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -403,10 +487,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; @@ -420,13 +505,17 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", @@ -447,13 +536,17 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16..919434a6 100644 --- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140cf..a6b826db 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ - - - - + + - - + + diff --git a/ios/Runner/.DS_Store b/ios/Runner/.DS_Store new file mode 100644 index 00000000..a8b55693 Binary files /dev/null and b/ios/Runner/.DS_Store differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png new file mode 100644 index 00000000..eef2a67c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png new file mode 100644 index 00000000..5edc1f6d Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024 1.png new file mode 100644 index 00000000..6506e482 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png new file mode 100644 index 00000000..6506e482 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png new file mode 100644 index 00000000..0b06be4f Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/120 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/120 1.png new file mode 100644 index 00000000..2bf25edb Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/120 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/120 2.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/120 2.png new file mode 100644 index 00000000..2bf25edb Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/120 2.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png new file mode 100644 index 00000000..2bf25edb Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png new file mode 100644 index 00000000..846eff6d Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png new file mode 100644 index 00000000..2ee6146d Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/152 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/152 1.png new file mode 100644 index 00000000..de8394eb Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/152 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png new file mode 100644 index 00000000..de8394eb Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png new file mode 100644 index 00000000..8d43d731 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/167 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/167 1.png new file mode 100644 index 00000000..925a123f Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/167 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png new file mode 100644 index 00000000..925a123f Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png new file mode 100644 index 00000000..b4869ae5 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/180 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/180 1.png new file mode 100644 index 00000000..4708a9b8 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/180 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png new file mode 100644 index 00000000..4708a9b8 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png new file mode 100644 index 00000000..8fa0cb21 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png new file mode 100644 index 00000000..434971aa Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png new file mode 100644 index 00000000..899dc84c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png new file mode 100644 index 00000000..dfeb88fe Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png new file mode 100644 index 00000000..9bb5b797 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png new file mode 100644 index 00000000..a71886e8 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/40 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/40 1.png new file mode 100644 index 00000000..6b3dd97b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/40 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png new file mode 100644 index 00000000..6b3dd97b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png new file mode 100644 index 00000000..50f41c5b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png new file mode 100644 index 00000000..eea037f2 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png new file mode 100644 index 00000000..f8815ff6 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png new file mode 100644 index 00000000..8329380b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png new file mode 100644 index 00000000..35e4264a Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/58 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/58 1.png new file mode 100644 index 00000000..64997665 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/58 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png new file mode 100644 index 00000000..64997665 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png new file mode 100644 index 00000000..15ec4ff8 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png new file mode 100644 index 00000000..fdde0d29 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png new file mode 100644 index 00000000..d0ad98b8 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png new file mode 100644 index 00000000..559ff236 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png new file mode 100644 index 00000000..5c40b240 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/80 1.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/80 1.png new file mode 100644 index 00000000..dff295c9 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/80 1.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/80 2.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/80 2.png new file mode 100644 index 00000000..dff295c9 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/80 2.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png new file mode 100644 index 00000000..dff295c9 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png new file mode 100644 index 00000000..38777e15 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png new file mode 100644 index 00000000..16398da6 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png new file mode 100644 index 00000000..e33c3b1b Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index 004a4f77..3b2547e2 100644 --- a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -27,39 +27,43 @@ "size" : "29x29" }, { - "filename" : "Icon-App-20x20@2x.png", + "filename" : "80 1.png", "idiom" : "iphone", "scale" : "2x", "size" : "40x40" }, { + "filename" : "120 1.png", "idiom" : "iphone", "scale" : "3x", "size" : "40x40" }, { - "filename" : "", + "filename" : "120 2.png", "idiom" : "iphone", "scale" : "2x", "size" : "60x60" }, { - "filename" : "", + "filename" : "180 1.png", "idiom" : "iphone", "scale" : "3x", "size" : "60x60" }, { + "filename" : "40 1.png", "idiom" : "ipad", "scale" : "2x", "size" : "20x20" }, { + "filename" : "58 1.png", "idiom" : "ipad", "scale" : "2x", "size" : "29x29" }, { + "filename" : "80 2.png", "idiom" : "ipad", "scale" : "2x", "size" : "40x40" @@ -71,16 +75,19 @@ "size" : "76x76" }, { + "filename" : "152 1.png", "idiom" : "ipad", "scale" : "2x", "size" : "76x76" }, { + "filename" : "167 1.png", "idiom" : "ipad", "scale" : "2x", "size" : "83.5x83.5" }, { + "filename" : "1024 1.png", "idiom" : "ios-marketing", "scale" : "1x", "size" : "1024x1024" diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 6ce701e8..00000000 Binary files a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 8397f756..fb188418 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -26,6 +26,13 @@ LaunchScreen UIMainStoryboardFile Main + NSPhotoLibraryUsageDescription + UserPhotoUpload + UIBackgroundModes + + fetch + remote-notification + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait diff --git a/lib/presentation/auth/auth_screen/auth_screen.dart b/lib/presentation/auth/auth_screen/auth_screen.dart index b85786d6..e934925b 100644 --- a/lib/presentation/auth/auth_screen/auth_screen.dart +++ b/lib/presentation/auth/auth_screen/auth_screen.dart @@ -30,7 +30,9 @@ class AuthScreen extends StatelessWidget { return Scaffold( resizeToAvoidBottomInset: false, appBar: _buildAppBar(context), - body: Container( + body:GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Container( width: double.maxFinite, padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), child: Column(children: [ @@ -85,7 +87,7 @@ class AuthScreen extends StatelessWidget { buttonStyle: CustomButtonStyles.outlinePrimaryTL15, onPressed: onTapAuth(state, context)); }), - ]))); + ])))); } onTapAuth(AuthState state, BuildContext context) { diff --git a/lib/presentation/chat/chat_screen/bloc/chat_bloc.dart b/lib/presentation/chat/chat_screen/bloc/chat_bloc.dart index 47ed9dec..0f4a2add 100644 --- a/lib/presentation/chat/chat_screen/bloc/chat_bloc.dart +++ b/lib/presentation/chat/chat_screen/bloc/chat_bloc.dart @@ -1,5 +1,9 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:hive/hive.dart'; +import 'package:http/http.dart' as http; +import 'dart:convert'; import '/core/app_export.dart'; import 'package:eatvio_app/presentation/chat/chat_screen/models/chat_model.dart'; part 'chat_event.dart'; @@ -15,6 +19,42 @@ class ChatBloc extends Bloc { ChatInitialEvent event, Emitter emit, ) async { - emit(state.copyWith(chatModelObj: state.chatModelObj?.copyWith())); + try { + final box = await Hive.openBox('token'); + final token = box.get('token'); + if (token == null) { + NavigatorService.popAndPushNamed( + AppRoutes.authScreen, + ); + } + final int id = 1; + final response = await http.get( + Uri.parse(dotenv.env['SERVER_ROOT']! + '/chat/$id/show'), + headers: { + 'Authorization': 'Bearer $token', + }, + ); + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + print(data['chatRooms']); + if (data is Map && data.containsKey('chatRooms')) { + if (state is ChatLoadedState) { + var currentState = state as ChatLoadedState; + emit(currentState.copyWith()); + } else { + emit(ChatLoadedState()); + } + } else { + // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку + emit(ChatErrorState('Некоторые необходимые данные отсутствуют.')); + } + } else { + // Статус ответа не равен 200, обрабатываем ошибку + emit(ChatErrorState('Ошибка сервера: ${response.statusCode}')); + } + } catch (e) { + // Ошибка при декодировании JSON или другая ошибка выполнения + emit(ChatErrorState('Ошибка при получении данных о чатах: $e')); + } } } diff --git a/lib/presentation/chat/chat_screen/bloc/chat_state.dart b/lib/presentation/chat/chat_screen/bloc/chat_state.dart index 20be159f..aae133dc 100644 --- a/lib/presentation/chat/chat_screen/bloc/chat_state.dart +++ b/lib/presentation/chat/chat_screen/bloc/chat_state.dart @@ -3,8 +3,26 @@ part of 'chat_bloc.dart'; /// Represents the state of Chat in the application. +/// + class ChatState extends Equatable { ChatState({ + this.chatModelObj, + }); + + ChatModel? chatModelObj; + + @override + List get props => [chatModelObj]; + ChatState copyWith({ChatModel? chatModelObj}) { + return ChatState( + chatModelObj: chatModelObj ?? this.chatModelObj, + ); + } +} + +class ChatLoadedState extends ChatState { + ChatLoadedState({ this.selectedDropDownValue, this.chatModelObj, }); @@ -23,9 +41,21 @@ class ChatState extends Equatable { ChatModel? chatModelObj, }) { return ChatState( - selectedDropDownValue: - selectedDropDownValue ?? this.selectedDropDownValue, chatModelObj: chatModelObj ?? this.chatModelObj, ); } } + +class ChatErrorState extends ChatState { + final String errorMessage; + + ChatErrorState(this.errorMessage); + + @override + List get props => [errorMessage]; +} + +class ChatInitialState extends ChatState { + ChatInitialState({required ChatModel chatModelObj}) + : super(chatModelObj: chatModelObj); +} diff --git a/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart b/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart index 04059200..740dbab7 100644 --- a/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart +++ b/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart @@ -1,5 +1,11 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:hive/hive.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'dart:convert'; import '/core/app_export.dart'; import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_select_model.dart'; import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entry.dart'; // ignore: must_be_immutable @@ -7,43 +13,78 @@ part 'chat_select_event.dart'; part 'chat_select_state.dart'; /// A bloc that manages the state of a ChatSelect according to the event that is dispatched to it. +/// + class ChatSelectBloc extends Bloc { ChatSelectBloc(ChatSelectState initialState) : super(initialState) { on(_onInitialize); } - List fillChatEntryList() { - return [ - ChatItemModel( - userImage: ImageConstant.imgLogo, - username: "Ксения Обрамова", - dateText: "9/29", - greetingText: "Привет, хорошая статья"), - ChatItemModel( - userImage: ImageConstant.imgLogo, - username: "Ксения Обрамова", - dateText: "9/29", - greetingText: "Привет, хорошая статья"), - ChatItemModel( - userImage: ImageConstant.imgLogo, - username: "Данил Иванов", - dateText: "9/29", - greetingText: "Посоветуй пожалуйста рецепт..."), - ChatItemModel( - userImage: ImageConstant.imgLogo, - username: "Данил Иванов", - dateText: "9/29", - greetingText: "Посоветуй пожалуйста рецепт...") - ]; + List fillChatEntryList(List chatRooms) { + List chats = []; + for (int i = 0; i < chatRooms.length; i++) { + String text = chatRooms[i]['last_message']['data']; + if (chatRooms[i]['last_message']['is_author_from_user']) { + text = "Вы: " + text; + } + chats.add(ChatItemModel( + id: chatRooms[i]['id'], + userImage: chatRooms[i]['users']['to_chat_user'] + ['profile_photo_path'], + username: chatRooms[i]['users']['to_chat_user']['name'], + dateText: DateFormat('dd.MM').format( + DateTime.parse(chatRooms[i]['last_message']['updated_at'])), + greetingText: text)); + } + return chats; } - _onInitialize( + Future _onInitialize( ChatSelectInitialEvent event, Emitter emit, ) async { - emit(state.copyWith( - chatSelectModelObj: state.chatSelectModelObj?.copyWith( - userprofileItemList: fillChatEntryList(), - ))); + try { + final box = await Hive.openBox('token'); + final token = box.get('token'); + if (token == null) { + NavigatorService.popAndPushNamed( + AppRoutes.authScreen, + ); + } + final response = await http.get( + Uri.parse(dotenv.env['SERVER_ROOT']! + '/chat/index'), + headers: { + 'Authorization': 'Bearer $token', + }, + ); + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + print(data['chatRooms']); + if (data is Map && data.containsKey('chatRooms')) { + if (state is ChatSelectLoadedState) { + var currentState = state as ChatSelectLoadedState; + emit(currentState.copyWith( + chatSelectModelObj: currentState.chatSelectModelObj, + chatRooms: currentState.chatRooms, + )); + } else { + emit(ChatSelectLoadedState( + chatRooms: fillChatEntryList(data['chatRooms']), + //chatRooms: [], + )); + } + } else { + // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку + emit(ChatSelectErrorState( + 'Некоторые необходимые данные отсутствуют.')); + } + } else { + // Статус ответа не равен 200, обрабатываем ошибку + emit(ChatSelectErrorState('Ошибка сервера: ${response.statusCode}')); + } + } catch (e) { + // Ошибка при декодировании JSON или другая ошибка выполнения + emit(ChatSelectErrorState('Ошибка при получении данных о чатах: $e')); + } } } diff --git a/lib/presentation/chat/chat_select_screen/bloc/chat_select_state.dart b/lib/presentation/chat/chat_select_screen/bloc/chat_select_state.dart index 7f56519e..e5f1262a 100644 --- a/lib/presentation/chat/chat_select_screen/bloc/chat_select_state.dart +++ b/lib/presentation/chat/chat_select_screen/bloc/chat_select_state.dart @@ -5,27 +5,54 @@ part of 'chat_select_bloc.dart'; /// Represents the state of ChatSelect in the application. class ChatSelectState extends Equatable { ChatSelectState({ - this.selectedDropDownValue, this.chatSelectModelObj, }); - SelectionPopupModel? selectedDropDownValue; - ChatSelectModel? chatSelectModelObj; @override - List get props => [ - selectedDropDownValue, - chatSelectModelObj, - ]; - ChatSelectState copyWith({ - SelectionPopupModel? selectedDropDownValue, - ChatSelectModel? chatSelectModelObj, - }) { + List get props => [chatSelectModelObj]; + ChatSelectState copyWith({ChatSelectModel? chatSelectModelObj}) { return ChatSelectState( - selectedDropDownValue: - selectedDropDownValue ?? this.selectedDropDownValue, chatSelectModelObj: chatSelectModelObj ?? this.chatSelectModelObj, ); } } + +class ChatSelectInitialState extends ChatSelectState { + ChatSelectInitialState({required ChatSelectModel chatSelectModelObj}) + : super(chatSelectModelObj: chatSelectModelObj); +} + +class ChatSelectLoadedState extends ChatSelectState { + ChatSelectLoadedState({ + this.chatRooms, + this.searchController, + this.chatSelectModelObj, + }) : super(chatSelectModelObj: null); + List? chatRooms; + TextEditingController? searchController; + ChatSelectModel? chatSelectModelObj; + @override + List get props => [chatSelectModelObj, chatRooms, searchController]; + ChatSelectLoadedState copyWith({ + ChatSelectModel? chatSelectModelObj, + TextEditingController? searchController, + List? chatRooms, + }) { + return ChatSelectLoadedState( + chatSelectModelObj: chatSelectModelObj ?? this.chatSelectModelObj, + chatRooms: chatRooms ?? this.chatRooms, + searchController: searchController ?? this.searchController, + ); + } +} + +class ChatSelectErrorState extends ChatSelectState { + final String errorMessage; + + ChatSelectErrorState(this.errorMessage); + + @override + List get props => [errorMessage]; +} diff --git a/lib/presentation/chat/chat_select_screen/chat_select_screen.dart b/lib/presentation/chat/chat_select_screen/chat_select_screen.dart index f92e2e3b..dea9d3bc 100644 --- a/lib/presentation/chat/chat_select_screen/chat_select_screen.dart +++ b/lib/presentation/chat/chat_select_screen/chat_select_screen.dart @@ -17,87 +17,95 @@ class ChatSelectScreen extends StatelessWidget { child: ChatSelectScreen()); } - @override Widget build(BuildContext context) { - mediaQueryData = MediaQuery.of(context); - return SafeArea( - child: Scaffold( - resizeToAvoidBottomInset: false, - body: Container( - width: double.maxFinite, - decoration: AppDecoration.fillGray, - child: Column( - children: [ - SizedBox(height: 30.v), - Container( - margin: EdgeInsets.only( - left: 16.h, - right: 20.h, - ), - padding: EdgeInsets.all(12.h), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: const BorderRadius.all(Radius.circular(12)), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 2, - blurRadius: 5, - offset: Offset(0, 3), - ), - ], - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - BlocSelector( - selector: (state) => TextEditingController(), - builder: (context, searchController) { - return CustomSearchView( - controller: searchController, - hintText: "Поиск", - ); - }, - ), - SizedBox(height: 20.v), - _buildChatList(context) - ], - ), - ) - ], - ), - ), - bottomNavigationBar: _buildBottomBar(context)), - ); - } - - _buildChatList(BuildContext context) { - return BlocSelector( - selector: (state) => state.chatSelectModelObj, - builder: (context, chatSelectModelObj) { - return ListView.separated( - shrinkWrap: true, - separatorBuilder: (context, index) { - return SizedBox( - height: 10.v, - ); - }, - itemCount: chatSelectModelObj?.userprofileItemList.length ?? 0, - itemBuilder: (context, index) { - ChatItemModel model = - chatSelectModelObj?.userprofileItemList[index] ?? - ChatItemModel(); - return UserprofileItemWidget( - model, - ); - }, - ); + return BlocBuilder( + builder: (context, state) { + if (state is ChatSelectInitialState) { + // Это начальное состояние, данные ещё не загружены. + return Container( + color: Colors.white, + ); + } else if (state is ChatSelectLoadedState) { + // Данные загружены, можно строить экран. + return _buildScreen(context, state); + } else if (state is ChatSelectErrorState) { + // Произошла ошибка при загрузке данных. + return Center(child: Text(state.errorMessage)); + } else { + // Другие состояния, если они есть. + return Container(); // Пустой контейнер для необработанных состояний. + } }, ); } - _buildBottomBar(BuildContext context) { - return CustomBottomBar(onChanged: (BottomBarEnum type) {}); + _buildScreen(BuildContext context, ChatSelectLoadedState state) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + body: Container( + width: double.maxFinite, + decoration: AppDecoration.fillGray, + child: ListView( + children: [ + SizedBox(height: 30.v), + Container( + margin: EdgeInsets.only( + left: 16.h, + right: 20.h, + bottom: 10.h, + ), + padding: EdgeInsets.all(12.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.all(Radius.circular(12)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CustomSearchView( + controller: state.searchController, + hintText: "Поиск", + ), + SizedBox(height: 20.v), + _buildChatList(context, state), + ], + ), + ) + ], + ), + ), + bottomNavigationBar: _buildBottomBar(context))); } } + +_buildChatList(BuildContext context, ChatSelectLoadedState state) { + return ListView.separated( + shrinkWrap: true, + separatorBuilder: (context, index) { + return SizedBox( + height: 10.v, + ); + }, + itemCount: state.chatRooms?.length ?? 0, + itemBuilder: (context, index) { + ChatItemModel model = state.chatRooms?[index]; + return ChatEntryWidget( + model, + ); + }, + ); +} + +_buildBottomBar(BuildContext context) { + return CustomBottomBar(onChanged: (BottomBarEnum type) {}); +} diff --git a/lib/presentation/chat/chat_select_screen/models/chat_entry.dart b/lib/presentation/chat/chat_select_screen/models/chat_entry.dart index 40fb78ef..6738afb8 100644 --- a/lib/presentation/chat/chat_select_screen/models/chat_entry.dart +++ b/lib/presentation/chat/chat_select_screen/models/chat_entry.dart @@ -9,12 +9,12 @@ class ChatItemModel { this.username, this.dateText, this.greetingText, - this.id}) { + required this.id}) { userImage = userImage ?? ImageConstant.imageNotFound; - username = username ?? "Ксения Обрамова"; - dateText = dateText ?? "9/29"; - greetingText = greetingText ?? "Привет, хорошая статья"; - id = id ?? ""; + username = username; + dateText = dateText; + greetingText = greetingText; + id = id; } String? userImage; @@ -25,5 +25,5 @@ class ChatItemModel { String? greetingText; - String? id; + String id; } diff --git a/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart b/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart index 4a3b9669..cc47e820 100644 --- a/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart +++ b/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart @@ -6,15 +6,15 @@ import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entr /// This class defines the variables used in the [chat_select_screen], /// and is typically used to hold data that is passed between different parts of the application. class ChatSelectModel extends Equatable { - ChatSelectModel({this.userprofileItemList = const []}); + ChatSelectModel({this.chatList = const []}); - List userprofileItemList; - ChatSelectModel copyWith({List? userprofileItemList}) { + List chatList; + ChatSelectModel copyWith({List? chatList}) { return ChatSelectModel( - userprofileItemList: userprofileItemList ?? this.userprofileItemList, + chatList: chatList ?? this.chatList, ); } @override - List get props => [userprofileItemList]; + List get props => [chatList]; } diff --git a/lib/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart b/lib/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart index 0df63990..a26b602b 100644 --- a/lib/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart +++ b/lib/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart @@ -1,16 +1,18 @@ // ignore_for_file: must_be_immutable import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entry.dart'; +import 'package:cached_network_image/cached_network_image.dart'; -class UserprofileItemWidget extends StatelessWidget { - UserprofileItemWidget(this.userprofileItemModelObj, {Key? key}) +class ChatEntryWidget extends StatelessWidget { + ChatEntryWidget(this.chatEntryObj, {Key? key}) : super( key: key, ); - ChatItemModel userprofileItemModelObj; + ChatItemModel chatEntryObj; @override Widget build(BuildContext context) { @@ -23,14 +25,28 @@ class UserprofileItemWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - CustomImageView( - imagePath: userprofileItemModelObj.userImage!, + CachedNetworkImage( + imageUrl: dotenv.env['STORAGE_URL']! + chatEntryObj.userImage!, + imageBuilder: (context, imageProvider) => CircleAvatar( + backgroundImage: imageProvider, + radius: 25, + ), + placeholder: (context, url) => CircularProgressIndicator(), + errorWidget: (context, url, error) => CircleAvatar( + child: Icon(Icons.person), + backgroundColor: Colors.white, + radius: 25, + ), + ), + /*CustomImageView( + imagePath: + dotenv.env['STORAGE_URL']! + chatEntryObj.userImage!, height: 60.adaptSize, width: 60.adaptSize, radius: BorderRadius.circular( 30.h, ), - ), + ),*/ Expanded( child: Padding( padding: EdgeInsets.only( @@ -39,7 +55,11 @@ class UserprofileItemWidget extends StatelessWidget { bottom: 11.v, ), child: GestureDetector( - onTap: () => Navigator.pushNamed(context, AppRoutes.chatScreen), + onTap: () => Navigator.pushNamed( + context, + AppRoutes.chatScreen, + arguments: chatEntryObj.id, + ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -48,7 +68,9 @@ class UserprofileItemWidget extends StatelessWidget { child: Row( children: [ Text( - userprofileItemModelObj.username!, + chatEntryObj.username!.length <= 15 + ? chatEntryObj.username! + : chatEntryObj.username!.substring(0, 15) + '...', style: theme.textTheme.titleMedium, ), Spacer(), @@ -64,7 +86,7 @@ class UserprofileItemWidget extends StatelessWidget { Padding( padding: EdgeInsets.only(left: 6.h), child: Text( - userprofileItemModelObj.dateText!, + chatEntryObj.dateText!, style: theme.textTheme.bodyMedium, ), ) @@ -73,7 +95,7 @@ class UserprofileItemWidget extends StatelessWidget { ), SizedBox(height: 6.v), Text( - userprofileItemModelObj.greetingText!, + chatEntryObj.greetingText!, style: CustomTextStyles.bodyMediumBluegray800, ) ], diff --git a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart index 20df3530..44741105 100644 --- a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart +++ b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart @@ -38,6 +38,7 @@ class DiaryEditBloc extends Bloc { on(_sendModeration); on( reloadScreen); //пользователь нажимает "Добавить комментарий" + on(_clearInput); } Future _onInitialize( @@ -547,6 +548,17 @@ class DiaryEditBloc extends Bloc { } } + + FutureOr _clearInput( + ClearInput event, Emitter emit) { + if (state is DiaryEditLoadedState) { + var currentState = state as DiaryEditLoadedState; + DiaryEditLoadedState updatedState = currentState.copyWith( + ); + emit(updatedState); + } + } + FutureOr _changePortion( ChangePortion event, Emitter emit) { if (state is DiaryEditLoadedState) { diff --git a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_event.dart b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_event.dart index 08b1e90a..8185fa28 100644 --- a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_event.dart +++ b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_event.dart @@ -122,6 +122,15 @@ class ChangeMeal extends DiaryEditEvent { List get props => [value, meals]; } + +class ClearInput extends DiaryEditEvent { + ClearInput({required this.value}); + + TextEditingController value; + @override + List get props => [value]; +} + class ChangePortion extends DiaryEditEvent { ChangePortion({required this.value}); diff --git a/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart b/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart index b189b214..1e81c626 100644 --- a/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart +++ b/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart @@ -376,7 +376,6 @@ class DiaryEditScreen extends StatelessWidget { ) { if (state.isAdded) { print("Clear"); - productEditingController.clear(); } return CustomTextFormField( hintText: "Введите название продукта", diff --git a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart index eab8dd94..b0359fd1 100644 --- a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart +++ b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart @@ -34,7 +34,7 @@ class MyProfileBloc extends Bloc { ); // Если токен есть, запускаем приложение } //final token = - // "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a"; + // "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1ne AggmpR2TidVGDPN34fa201a"; final response = await http.get( Uri.parse(dotenv.env['SERVER_ROOT']! + '/profile/index'), headers: { @@ -95,6 +95,7 @@ class MyProfileBloc extends Bloc { selectedCity: currentState.selectedCity, selectedCountry: currentState.selectedCountry, selectedActivity: currentState.selectedActivity, + myProfileModelObj: currentState.myProfileModelObj, )); } else { var plans = [] diff --git a/lib/presentation/profile/my_profile_screen/my_profile_screen.dart b/lib/presentation/profile/my_profile_screen/my_profile_screen.dart index d02f26d2..ad417337 100644 --- a/lib/presentation/profile/my_profile_screen/my_profile_screen.dart +++ b/lib/presentation/profile/my_profile_screen/my_profile_screen.dart @@ -187,7 +187,7 @@ class MyProfileScreen extends StatelessWidget { _buildCarousel(BuildContext contex, MyProfileLoadedState state) { return CarouselSlider( - options: CarouselOptions(height: 265.0), + options: CarouselOptions(height: 320.0), items: [1, 2, 3].map((chartType) { return Builder( builder: (BuildContext context) { @@ -800,52 +800,56 @@ class MyProfileScreen extends StatelessWidget { //final digitsOnly = FilteringTextInputFormatter.digitsOnly; return AlertDialog( title: Center(child: Text("Добавить замер")), - content: ListView( - children: [ - Padding( - padding: EdgeInsets.symmetric(vertical: 5.v), - child: Text("chest_circumference".tr, - style: theme.textTheme.bodyLarge), - ), - SizedBox(height: 5.v), - CustomTextFormField( - controller: state.chestCircumferenceController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter - .digitsOnly, // Ограничение ввода только цифрами + + content: SizedBox( + width: 200, // Ширина диалогового окна + height: 300, // Высота диалогового окна + child: ListView( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 5.v), + child: Text("chest_circumference".tr, + style: theme.textTheme.bodyLarge), + ), + SizedBox(height: 5.v), + CustomTextFormField( + controller: state.chestCircumferenceController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter + .digitsOnly, // Ограничение ввода только цифрами + ], + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 15.v), + child: Text("waist_circumference".tr, + style: theme.textTheme.bodyLarge), + ), + SizedBox(height: 5.v), + CustomTextFormField( + controller: state.waistCircumferenceController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter + .digitsOnly, // Ограничение ввода только цифрами + ], + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 15.v), + child: Text("hip_circumference".tr, + style: theme.textTheme.bodyLarge), + ), + SizedBox(height: 5.v), + CustomTextFormField( + controller: state.hipCircumferenceController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter + .digitsOnly, // Ограничение ввода только цифрами + ], + ), ], - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 15.v), - child: Text("waist_circumference".tr, - style: theme.textTheme.bodyLarge), - ), - SizedBox(height: 5.v), - CustomTextFormField( - controller: state.waistCircumferenceController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter - .digitsOnly, // Ограничение ввода только цифрами - ], - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 15.v), - child: Text("hip_circumference".tr, - style: theme.textTheme.bodyLarge), - ), - SizedBox(height: 5.v), - CustomTextFormField( - controller: state.hipCircumferenceController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter - .digitsOnly, // Ограничение ввода только цифрами - ], - ), - ], - ), + )), actions: [ TextButton( onPressed: onTapOk(context), @@ -912,31 +916,33 @@ class MyProfileScreen extends StatelessWidget { context: context, builder: (context) { return AlertDialog( - title: Center(child: Text("add_measure".tr)), - content: ListView( - children: [ - Padding( - padding: EdgeInsets.symmetric(vertical: 5.v), - child: Text("weight".tr, style: theme.textTheme.bodyLarge), - ), - SizedBox(height: 5.v), - CustomTextFormField( - controller: state.weightController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter - .digitsOnly, // Ограничение ввода только цифрами - ], - ), - ], + content: SizedBox( + width: 200, // Ширина диалогового окна + height: 100, // Высота диалогового окна + child: ListView( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 5), + child: Text("weight".tr, style: theme.textTheme.bodyLarge), + ), + SizedBox(height: 5), + CustomTextFormField( + controller: state.weightController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + ), + ], + ), ), actions: [ TextButton( - onPressed: onTapOk(context), + onPressed: () => Navigator.of(context).pop(), child: Text("Отмена", style: theme.textTheme.bodyLarge), ), TextButton( - onPressed: addWeight(state, context), + onPressed: () => saveWeight(state, context), child: Text("Изменить", style: CustomTextStyles.titleMediumBlack.copyWith( color: Colors.blue, @@ -944,13 +950,17 @@ class MyProfileScreen extends StatelessWidget { ), ], backgroundColor: Colors.white, - titlePadding: EdgeInsets.all( - 20.0), // Можете настроить отступы по вашему желанию + titlePadding: EdgeInsets.all(20.0), ); }, ); } + void saveWeight(MyProfileLoadedState state, BuildContext context) { + addWeight(state, context); + Navigator.of(context).pop(); // Закрыть диалоговое окно после изменения веса + } + onTapOk(BuildContext context) { return () { Navigator.pop(context); diff --git a/lib/widgets/app_bar/appbar_title_image.dart b/lib/widgets/app_bar/appbar_title_image.dart index e15f1c52..4ef20de2 100644 --- a/lib/widgets/app_bar/appbar_title_image.dart +++ b/lib/widgets/app_bar/appbar_title_image.dart @@ -35,6 +35,5 @@ class AppbarTitleImage extends StatelessWidget { } void onTapCall() { - onTap!.call(); } }