fix: 图片提交4x,提示画质。iOS logo提交;

This commit is contained in:
csw 2026-07-01 16:24:15 +08:00
parent 2f1ec27802
commit 9e10608245
85 changed files with 1027 additions and 645 deletions

View File

@ -1,6 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application <application
android:label="skywood" android:label="Glimzo"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 57 KiB

BIN
assets/common/applogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 993 B

BIN
assets/common/btn_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

BIN
assets/common/no_data.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 34 KiB

BIN
assets/mine/collection.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -10,11 +10,13 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
65AF1B16E4A6C37A6ACC85FB /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50D45A40C0996859C0A2D64D /* Pods_RunnerTests.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; }; 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
C9EB92C29F874D79B657D24A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555E8D26F0182AE8F37D1C59 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -41,35 +43,61 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0695C2418C491EC90FD98053 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
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>"; };
29B4395BBF135D84DF06B698 /* 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 = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
50D45A40C0996859C0A2D64D /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
555E8D26F0182AE8F37D1C59 /* 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 = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; }; 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9785CFD2D21F8A504CAC82C3 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AE15EBB625F9CFD97308BAA5 /* 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 = "<group>"; };
B906E66169FF427012694455 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
D75CAD8907D4A38E83BE6574 /* 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 = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
0656031C13171FB955899F99 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
65AF1B16E4A6C37A6ACC85FB /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = { 97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
C9EB92C29F874D79B657D24A /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
2A7F196FEE0498D81BB7A70C /* Frameworks */ = {
isa = PBXGroup;
children = (
555E8D26F0182AE8F37D1C59 /* Pods_Runner.framework */,
50D45A40C0996859C0A2D64D /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
331C8082294A63A400263BE5 /* RunnerTests */ = { 331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -78,6 +106,19 @@
path = RunnerTests; path = RunnerTests;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
508C663161B7C6696D1FF8B7 /* Pods */ = {
isa = PBXGroup;
children = (
AE15EBB625F9CFD97308BAA5 /* Pods-Runner.debug.xcconfig */,
29B4395BBF135D84DF06B698 /* Pods-Runner.release.xcconfig */,
D75CAD8907D4A38E83BE6574 /* Pods-Runner.profile.xcconfig */,
0695C2418C491EC90FD98053 /* Pods-RunnerTests.debug.xcconfig */,
B906E66169FF427012694455 /* Pods-RunnerTests.release.xcconfig */,
9785CFD2D21F8A504CAC82C3 /* Pods-RunnerTests.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -96,6 +137,8 @@
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */, 331C8082294A63A400263BE5 /* RunnerTests */,
508C663161B7C6696D1FF8B7 /* Pods */,
2A7F196FEE0498D81BB7A70C /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -131,8 +174,10 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = ( buildPhases = (
7EECBAA2B332419C7456E3D3 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */, 331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */, 331C807F294A63A400263BE5 /* Resources */,
0656031C13171FB955899F99 /* Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -148,12 +193,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
ED357041BDF6B3C4EED6BE91 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
429E661A46AA3E4BB3AC50ED /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -241,6 +288,45 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
}; };
429E661A46AA3E4BB3AC50ED /* [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;
};
7EECBAA2B332419C7456E3D3 /* [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-RunnerTests-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;
};
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1; alwaysOutOfDate = 1;
@ -256,6 +342,28 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
ED357041BDF6B3C4EED6BE91 /* [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 */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
@ -369,6 +477,7 @@
DEVELOPMENT_TEAM = 2KBA4QW6M2; DEVELOPMENT_TEAM = 2KBA4QW6M2;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 18.6;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@ -383,6 +492,7 @@
}; };
331C8088294A63A400263BE5 /* Debug */ = { 331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 0695C2418C491EC90FD98053 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
@ -400,6 +510,7 @@
}; };
331C8089294A63A400263BE5 /* Release */ = { 331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = B906E66169FF427012694455 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
@ -415,6 +526,7 @@
}; };
331C808A294A63A400263BE5 /* Profile */ = { 331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 9785CFD2D21F8A504CAC82C3 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
@ -549,6 +661,7 @@
DEVELOPMENT_TEAM = 2KBA4QW6M2; DEVELOPMENT_TEAM = 2KBA4QW6M2;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 18.6;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@ -567,11 +680,13 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
"ASSETCATALOG_COMPILER_APPICON_NAME[sdk=iphoneos*]" = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 2KBA4QW6M2; DEVELOPMENT_TEAM = 2KBA4QW6M2;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 18.6;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",

View File

@ -4,4 +4,7 @@
<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "group:Runner.xcodeproj">
</FileRef> </FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace> </Workspace>

View File

@ -1,122 +1,122 @@
{ {
"images" : [ "images" : [
{ {
"size" : "20x20", "filename" : "app_logo2 14.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "20x20"
}, },
{ {
"size" : "20x20", "filename" : "app_logo2 9.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png", "scale" : "3x",
"scale" : "3x" "size" : "20x20"
}, },
{ {
"size" : "29x29", "filename" : "app_logo2 16.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png", "scale" : "1x",
"scale" : "1x" "size" : "29x29"
}, },
{ {
"size" : "29x29", "filename" : "app_logo2 11.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "29x29"
}, },
{ {
"size" : "29x29", "filename" : "app_logo2 5.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png", "scale" : "3x",
"scale" : "3x" "size" : "29x29"
}, },
{ {
"size" : "40x40", "filename" : "app_logo2 6.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "40x40"
}, },
{ {
"size" : "40x40", "filename" : "app_logo2 3.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png", "scale" : "3x",
"scale" : "3x" "size" : "40x40"
}, },
{ {
"size" : "60x60", "filename" : "app_logo2 4.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "60x60"
}, },
{ {
"size" : "60x60", "filename" : "app_logo2.png",
"idiom" : "iphone", "idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png", "scale" : "3x",
"scale" : "3x" "size" : "60x60"
}, },
{ {
"size" : "20x20", "filename" : "app_logo2 17.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png", "scale" : "1x",
"scale" : "1x" "size" : "20x20"
}, },
{ {
"size" : "20x20", "filename" : "app_logo2 13.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "20x20"
}, },
{ {
"size" : "29x29", "filename" : "app_logo2 15.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png", "scale" : "1x",
"scale" : "1x" "size" : "29x29"
}, },
{ {
"size" : "29x29", "filename" : "app_logo2 10.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "29x29"
}, },
{ {
"size" : "40x40", "filename" : "app_logo2 12.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png", "scale" : "1x",
"scale" : "1x" "size" : "40x40"
}, },
{ {
"size" : "40x40", "filename" : "app_logo2 7.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "40x40"
}, },
{ {
"size" : "76x76", "filename" : "app_logo2 8.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png", "scale" : "1x",
"scale" : "1x" "size" : "76x76"
}, },
{ {
"size" : "76x76", "filename" : "app_logo2 2.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "76x76"
}, },
{ {
"size" : "83.5x83.5", "filename" : "app_logo2 1.png",
"idiom" : "ipad", "idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png", "scale" : "2x",
"scale" : "2x" "size" : "83.5x83.5"
}, },
{ {
"size" : "1024x1024", "filename" : "applogo.png",
"idiom" : "ios-marketing", "idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png", "scale" : "1x",
"scale" : "1x" "size" : "1024x1024"
} }
], ],
"info" : { "info" : {
"version" : 1, "author" : "xcode",
"author" : "xcode" "version" : 1
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -7,7 +7,7 @@
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>Skywood</string> <string>Glimzo</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -15,7 +15,7 @@
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>skywood</string> <string>Glimzo</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>

View File

@ -0,0 +1,68 @@
import 'package:skywood/global/request/api_const.dart';
import 'package:skywood/global/request/app_request.dart';
import 'package:skywood/global/tool/sky_log.dart';
import 'package:skywood/utils/tools/token_manage.dart';
class EventClient {
static Future eventCreateHis({
required String shortPlayId,
required String videoId
}) {
// {"short_play_id": shortPlayId, "video_id": videoId}
Map<String, dynamic> params = {"short_play_id": shortPlayId, "video_id": videoId};
return AppRequest.post(ApiString.eventCreateHistory, data: params).then((value) {
SkyLog.print(value.data, tag: "eventCreateHis");
});
}
static Future eventEnterApp() {
return AppRequest.post(ApiString.eventUserEnterApp).then((value) {});
}
static Future<bool> eventOnline({String? oldToken}) {
String token = TokenManager().get();
if (token == '') return Future<bool>.value(false);
final body = <String, dynamic>{};
if (oldToken != null) body['token'] = oldToken;
return AppRequest.post(ApiString.eventUserOnline, data: body).then((value) {
return value.isSuccess;
});
}
static Future<bool> eventOLeaveApp({String? oldToken}) {
String token = TokenManager().get();
if (token == '') return Future<bool>.value(false);
final body = <String, dynamic>{};
if (oldToken != null) body['token'] = oldToken;
return AppRequest.post(ApiString.eventUserLeaveApp, data: body).then((value) {
return value.isSuccess;
});
}
//
static Future eventPlaySeconds({
required int shortPlayId,
required int videoId,
required int seconds,
}) {
return AppRequest.post(ApiString.eventPlaySeconds, data: {
"short_play_id": shortPlayId,
"video_id": videoId,
"play_seconds": seconds,
}).then((value) {});
}
//
static Future eventWatchTime({
required int shortPlayId,
required int seconds,
}) {
return AppRequest.post(ApiString.eventWatchTime, data: {
"short_play_id": shortPlayId,
//
"request_id": DateTime.now().millisecondsSinceEpoch,
"duration": seconds,
}).then((value) {});
}
}

View File

@ -1,7 +1,7 @@
final class ApiConst { final class ApiConst {
ApiConst._(); ApiConst._();
static const appName = 'skywood'; static const appName = 'Glimzo';
static const int pageSize = 12; static const int pageSize = 12;
static const String apiLink = 'https://api-quickeltv.quickeltv.com/quickeltv'; static const String apiLink = 'https://api-quickeltv.quickeltv.com/quickeltv';
@ -75,7 +75,7 @@ class ApiStringPlay {
static const String getWaterflowList = "/newShortPlay"; static const String getWaterflowList = "/newShortPlay";
/// getSearchHots GET /search/hots /// getSearchHots GET /search/hots
// getSearch GET /search query: search /// getSearch GET /search query: search
///==== collect POST /collect body: short_play_id, video_id ///==== collect POST /collect body: short_play_id, video_id
///==== cancelCollect POST /cancelCollect body: short_play_id ///==== cancelCollect POST /cancelCollect body: short_play_id
///==== getMyCollections GET /myCollections ///==== getMyCollections GET /myCollections

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:skywood/global/client/event_client.dart';
import 'package:skywood/global/request/app_request.dart'; import 'package:skywood/global/request/app_request.dart';
import 'package:skywood/global/tool/sky_routers.dart'; import 'package:skywood/global/tool/sky_routers.dart';
import 'package:skywood/main/main_root.dart'; import 'package:skywood/main/main_root.dart';
@ -28,12 +29,23 @@ Future<void> initServices() async {
await Get.putAsync(() async => UserController()); await Get.putAsync(() async => UserController());
} }
class ComApp extends StatelessWidget { class ComApp extends StatefulWidget {
const ComApp({super.key, required this.home, this.locale}); const ComApp({super.key, required this.home, this.locale});
final Widget home; final Widget home;
final Locale? locale; final Locale? locale;
@override
State<StatefulWidget> createState() {
return _ComAppState();
}
}
class _ComAppState extends State<ComApp> with WidgetsBindingObserver {
bool _appInForeground = true; //
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Locale locale = await AppLanguage.getLocale(); // Locale locale = await AppLanguage.getLocale();
@ -42,7 +54,7 @@ class ComApp extends StatelessWidget {
child: GetMaterialApp( child: GetMaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
translations: AppLanguage(), translations: AppLanguage(),
locale: locale ?? Get.deviceLocale, locale: widget.locale ?? Get.deviceLocale,
fallbackLocale: const Locale('en'), fallbackLocale: const Locale('en'),
initialBinding: AppBindings(), initialBinding: AppBindings(),
initialRoute: SkyPages.initial, initialRoute: SkyPages.initial,
@ -70,6 +82,62 @@ class ComApp extends StatelessWidget {
), ),
); );
} }
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
// _startPeriodicOnlineReport();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);
switch (state) {
case AppLifecycleState.inactive:
case AppLifecycleState.paused:
//
if (_appInForeground) {
print('💛应用不活跃');
_appInForeground = false;
_onAppPaused();
}
break;
case AppLifecycleState.resumed:
//
if (!_appInForeground) {
print('💚应用活跃');
_appInForeground = true;
_onAppResumed();
}
break;
case AppLifecycleState.detached:
case AppLifecycleState.hidden:
break;
}
}
//
void _onAppPaused() {
try {
EventClient.eventOLeaveApp();
} catch (err) { print(err.toString()); }
}
///
void _onAppResumed() {
try {
EventClient.eventEnterApp();
EventClient.eventOnline();
} catch (err) { print(err.toString()); }
}
} }
class AppBindings extends Bindings { class AppBindings extends Bindings {

View File

@ -1,19 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart'; import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/widget/player_bottom_widget.dart';
import 'package:skywood/pages/home/players/widget/sky_player_view.dart'; import 'package:skywood/pages/home/players/widget/sky_player_view.dart';
import 'package:skywood/utils/models/drama/skywood_detail.dart'; import 'package:skywood/utils/models/drama/skywood_detail.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart'; import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/models/drama/skywood_home.dart'; import 'package:skywood/utils/models/drama/skywood_episode.dart';
import 'package:skywood/utils/tools/app_toast.dart'; import 'package:skywood/utils/tools/app_toast.dart';
import 'package:skywood/utils/tools/widgets/sky_app_bar.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart'; import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
class DramaDetailPage extends StatefulWidget { class DramaDetailPage extends StatefulWidget {
const DramaDetailPage({super.key, const DramaDetailPage({super.key, required this.dramaBean});
required this.dramaBean,
});
final SkywoodDrama dramaBean; final SkywoodDrama dramaBean;
@ -24,36 +20,49 @@ class DramaDetailPage extends StatefulWidget {
} }
class _DramaDetailPageState extends State<DramaDetailPage> { class _DramaDetailPageState extends State<DramaDetailPage> {
SkywoodDetail? _detailBean; SkywoodDetail? _detailBean;
SkywoodEpisode? _selectedEpisode;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_getDetailDrama(); _getDetailDrama(
shortPlayId: widget.dramaBean.shortPlayId ?? 0,
shortPlayVideoId: widget.dramaBean.shortPlayVideoId ?? 0,
);
} }
void _getDetailDrama() { void _getDetailDrama({
print('currentEpisode===${widget.dramaBean.currentEpisode}'); required int shortPlayId,
required int shortPlayVideoId,
}) {
AppToast.showLottieLoading(); AppToast.showLottieLoading();
PlayClient.getVideoDetail( PlayClient.getVideoDetail(
shortPlayId: widget.dramaBean.shortPlayId ?? 0, shortPlayId: shortPlayId,
shortPlayVideoId: widget.dramaBean.shortPlayVideoId ?? 0 shortPlayVideoId: shortPlayVideoId,
).then((value) { ).then((value) {
AppToast.dismiss(); AppToast.dismiss();
if (!mounted) return;
setState(() { setState(() {
_detailBean = value; _detailBean = value;
}); });
}); });
} }
void _onSelectedEpisode(SkywoodEpisode episode) {
setState(() {
_selectedEpisode = episode;
});
_getDetailDrama(
shortPlayId: episode.shortPlayId,
shortPlayVideoId: episode.shortPlayVideoId,
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(backgroundColor: Colors.black, body: _bodyWidget());
backgroundColor: Colors.black,
body: _bodyWidget(),
);
} }
Widget _bodyWidget() { Widget _bodyWidget() {
@ -63,17 +72,29 @@ class _DramaDetailPageState extends State<DramaDetailPage> {
if (_detailBean != null) if (_detailBean != null)
Positioned( Positioned(
bottom: 0, left: 0, right: 0, top: 0, bottom: 0,
left: 0,
right: 0,
top: 0,
child: SkyPlayerView( child: SkyPlayerView(
key: ValueKey(
_selectedEpisode?.shortPlayVideoId ??
_detailBean?.videoInfo?.shortPlayVideoId ??
widget.dramaBean.shortPlayVideoId,
),
detailBean: _detailBean, detailBean: _detailBean,
dramaBean: widget.dramaBean, dramaBean: widget.dramaBean,
currentEpisode: _selectedEpisode?.episode,
onSelectedEpisode: _onSelectedEpisode,
), ),
), ),
Positioned( Positioned(
top: AppScreen.statusBarHeight + 5, left: 0, right: 0, top: AppScreen.statusBarHeight + 5,
left: 0,
right: 0,
child: _headerWidget(), child: _headerWidget(),
) ),
], ],
); );
} }
@ -88,14 +109,18 @@ class _DramaDetailPageState extends State<DramaDetailPage> {
icon: HelpImg.asset(ConstImg.back, width: 32), icon: HelpImg.asset(ConstImg.back, width: 32),
onPressed: () => HelpNav.back(), onPressed: () => HelpNav.back(),
), ),
Expanded(child: SkyText(text: widget.dramaBean.name, color: Colors.white, fontSize: 16, Expanded(
textAlign: TextAlign.center, child: SkyText(
fontWeight: FontWeight.bold, text: widget.dramaBean.name,
)), color: Colors.white,
SizedBox(width: 40,) fontSize: 16,
textAlign: TextAlign.center,
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 40),
], ],
), ),
); );
} }
}
}

View File

@ -6,7 +6,8 @@ import 'package:skywood/utils/models/drama/skywood_episode.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart'; import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
class DramaEspPage extends StatefulWidget { class DramaEspPage extends StatefulWidget {
const DramaEspPage({super.key, const DramaEspPage({
super.key,
required this.detail, required this.detail,
this.currentEpisode, this.currentEpisode,
this.onSelectedEpisode, this.onSelectedEpisode,
@ -14,7 +15,7 @@ class DramaEspPage extends StatefulWidget {
final SkywoodDetail detail; final SkywoodDetail detail;
final int? currentEpisode; final int? currentEpisode;
final Function(int)? onSelectedEpisode; final ValueChanged<SkywoodEpisode>? onSelectedEpisode;
@override @override
State<StatefulWidget> createState() { State<StatefulWidget> createState() {
@ -184,10 +185,11 @@ class _DramaEspPageState extends State<DramaEspPage> {
return GestureDetector( return GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: () { onTap: () {
if (_selectedEpisode == episode.episode) return;
setState(() { setState(() {
_selectedEpisode = episode.episode; _selectedEpisode = episode.episode;
}); });
widget.onSelectedEpisode?.call(_selectedEpisode); widget.onSelectedEpisode?.call(episode);
}, },
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/global/client/event_client.dart';
import 'package:skywood/global/client/play_client.dart'; import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/page/drama_esp_page.dart'; import 'package:skywood/pages/home/players/page/drama_esp_page.dart';
@ -15,6 +16,7 @@ class SkyPlayerView extends StatefulWidget {
final SkywoodDetail? detailBean; final SkywoodDetail? detailBean;
final SkywoodDrama dramaBean; final SkywoodDrama dramaBean;
final int? currentEpisode; final int? currentEpisode;
final ValueChanged<SkywoodEpisode>? onSelectedEpisode;
const SkyPlayerView({ const SkyPlayerView({
super.key, super.key,
@ -23,6 +25,7 @@ class SkyPlayerView extends StatefulWidget {
this.detailBean, this.detailBean,
required this.dramaBean, required this.dramaBean,
this.currentEpisode, this.currentEpisode,
this.onSelectedEpisode,
}); });
@override @override
@ -40,6 +43,8 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
Duration _totalDuration = Duration.zero; Duration _totalDuration = Duration.zero;
bool _isLiked = false; bool _isLiked = false;
SkywoodEpisode? _currentEpisode; SkywoodEpisode? _currentEpisode;
// his
bool _isReportedHis = false;
@override @override
void initState() { void initState() {
@ -47,14 +52,15 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
_initializePlayer(); _initializePlayer();
} }
// @override @override
// void didUpdateWidget(SkyPlayerView oldWidget) { void didUpdateWidget(SkyPlayerView oldWidget) {
// super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
// if (oldWidget.videoUrl != widget.videoUrl) { if (oldWidget.detailBean != widget.detailBean ||
// _disposeController(); oldWidget.currentEpisode != widget.currentEpisode) {
// _initializePlayer(); _disposeController();
// } _initializePlayer();
// } }
}
Future<void> _initializePlayer() async { Future<void> _initializePlayer() async {
setState(() { setState(() {
@ -66,18 +72,10 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
_isLiked = widget.dramaBean.isCollect ?? false; _isLiked = widget.dramaBean.isCollect ?? false;
}); });
int _esp = widget.currentEpisode ?? 0; _currentEpisode = _resolveCurrentEpisode();
String videoUrl = ''; String videoUrl = _currentEpisode?.videoUrl ?? '';
if (widget.detailBean != null) {
if (widget.detailBean!.episodeList.isNotEmpty) {
videoUrl = widget.detailBean!.episodeList[_esp].videoUrl;
_currentEpisode = widget.detailBean!.episodeList[_esp];
}
}
final controller = VideoPlayerController.networkUrl( final controller = VideoPlayerController.networkUrl(Uri.parse(videoUrl));
Uri.parse(videoUrl),
);
_controller = controller; _controller = controller;
_controllerCreated = true; _controllerCreated = true;
controller.addListener(_handlePlayerValueChanged); controller.addListener(_handlePlayerValueChanged);
@ -104,6 +102,17 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
void _handlePlayerValueChanged() { void _handlePlayerValueChanged() {
if (!mounted || !_controllerCreated) return; if (!mounted || !_controllerCreated) return;
_syncPlayerValue(); _syncPlayerValue();
final videoController = _controller;
final position = videoController.value.position;
final duration = videoController.value.duration;
if (_isPlaying && !_isReportedHis && position.inSeconds > 1) {
_isReportedHis = true;
EventClient.eventCreateHis(
shortPlayId: _currentEpisode!.shortPlayId.toString(),
videoId: _currentEpisode!.shortPlayVideoId.toString(),
);
}
} }
void _syncPlayerValue() { void _syncPlayerValue() {
@ -194,9 +203,7 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
Widget _buildLoadingView() { Widget _buildLoadingView() {
return Container( return Container(
color: Colors.black, color: Colors.black,
child: Center( child: Center(child: HelpImg.asset(ConstImg.loading, width: 110)),
child: HelpImg.asset(ConstImg.loading, width: 110),
),
); );
} }
@ -223,17 +230,39 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
} }
} }
SkywoodEpisode? _resolveCurrentEpisode() {
final detail = widget.detailBean;
if (detail == null || detail.episodeList.isEmpty) return null;
final int? episode =
widget.currentEpisode ??
detail.videoInfo?.episode ??
detail.videoInfo?.currentEpisode ??
detail.shortPlayInfo?.episode ??
detail.shortPlayInfo?.currentEpisode;
if (episode != null && episode > 0) {
for (final item in detail.episodeList) {
if (item.episode == episode) return item;
}
}
return detail.episodeList.first;
}
void _collectionDrama() { void _collectionDrama() {
if (_currentEpisode == null) return; if (_currentEpisode == null) return;
if (_isLiked) { if (_isLiked) {
PlayClient.cancelCollect(shortPlayId: _currentEpisode!.shortPlayId).then((value) { PlayClient.cancelCollect(shortPlayId: _currentEpisode!.shortPlayId).then((
value,
) {
setState(() { setState(() {
_isLiked = value; _isLiked = value;
}); });
}); });
} else { } else {
PlayClient.collect( PlayClient.collect(
shortPlayId: _currentEpisode!.shortPlayId, shortPlayId: _currentEpisode!.shortPlayId,
videoId: _currentEpisode!.shortPlayVideoId, videoId: _currentEpisode!.shortPlayVideoId,
).then((value) { ).then((value) {
setState(() { setState(() {
@ -257,8 +286,9 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
InkWell( InkWell(
onTap: () => _collectionDrama(), onTap: () => _collectionDrama(),
child: HelpImg.asset( child: HelpImg.asset(
_isLiked ? ConstImg.liked : ConstImg.unlike, _isLiked ? ConstImg.liked : ConstImg.unlike,
width: 40, height: 40 width: 40,
height: 40,
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
@ -282,7 +312,7 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
color: Colors.white, color: Colors.white,
), ),
SkyText( SkyText(
text: ' / EP.${detail.episodeList.length}', text: ' / EP.$totalEpisode',
fontSize: 13, fontSize: 13,
color: Colors.white.withAlpha(126), color: Colors.white.withAlpha(126),
), ),
@ -293,9 +323,6 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
), ),
).addInkWell( ).addInkWell(
onTap: () { onTap: () {
// HelpNav.showBottom(
// DramaEspPage(detail: detail, currentEpisode: currentEpisode),
// );
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
@ -307,12 +334,8 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
detail: detail, detail: detail,
currentEpisode: currentEpisode, currentEpisode: currentEpisode,
onSelectedEpisode: (episode) { onSelectedEpisode: (episode) {
Navigator.pop(context);
if (widget.detailBean != null) { widget.onSelectedEpisode?.call(episode);
if (widget.detailBean!.episodeList.isNotEmpty) {
_currentEpisode = widget.detailBean!.episodeList[episode];
}
}
}, },
), ),
); );
@ -361,9 +384,7 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
child: SliderTheme( child: SliderTheme(
data: SliderThemeData( data: SliderThemeData(
trackHeight: 3, // 3 trackHeight: 3, // 3
thumbShape: _ImageThumbShape( thumbShape: _ImageThumbShape(imagePath: ConstImg.playTag),
imagePath: ConstImg.playTag
),
overlayShape: const RoundSliderOverlayShape(overlayRadius: 3), overlayShape: const RoundSliderOverlayShape(overlayRadius: 3),
activeTrackColor: Colors.white, // = activeTrackColor: Colors.white, // =
inactiveTrackColor: Colors.white.withAlpha(126), // = inactiveTrackColor: Colors.white.withAlpha(126), // =
@ -404,6 +425,10 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
} }
int _getCurrentEpisode(SkywoodDetail detail) { int _getCurrentEpisode(SkywoodDetail detail) {
if (_currentEpisode?.episode != null && _currentEpisode!.episode > 0) {
return _currentEpisode!.episode;
}
final int? episode = final int? episode =
detail.videoInfo?.episode ?? detail.videoInfo?.episode ??
detail.videoInfo?.currentEpisode ?? detail.videoInfo?.currentEpisode ??
@ -419,18 +444,11 @@ class _VideoPlayerWidgetState extends State<SkyPlayerView> {
} }
} }
class _ImageThumbShape extends SliderComponentShape { class _ImageThumbShape extends SliderComponentShape {
final String imagePath; final String imagePath;
final double imageSize; final double imageSize = 16;
const _ImageThumbShape({ const _ImageThumbShape({required this.imagePath});
required this.imagePath,
this.imageSize = 16,
});
@override @override
Size getPreferredSize(bool isEnabled, bool isDiscrete) { Size getPreferredSize(bool isEnabled, bool isDiscrete) {
@ -439,19 +457,19 @@ class _ImageThumbShape extends SliderComponentShape {
@override @override
void paint( void paint(
PaintingContext context, PaintingContext context,
Offset center, { Offset center, {
required Animation<double> activationAnimation, required Animation<double> activationAnimation,
required Animation<double> enableAnimation, required Animation<double> enableAnimation,
required bool isDiscrete, required bool isDiscrete,
required TextPainter labelPainter, required TextPainter labelPainter,
required RenderBox parentBox, required RenderBox parentBox,
required SliderThemeData sliderTheme, required SliderThemeData sliderTheme,
required TextDirection textDirection, required TextDirection textDirection,
required double value, required double value,
required double textScaleFactor, required double textScaleFactor,
required Size sizeWithOverflow, required Size sizeWithOverflow,
}) { }) {
// 🔥 使 Image // 🔥 使 Image
final imageWidget = Image.asset( final imageWidget = Image.asset(
imagePath, imagePath,
@ -464,29 +482,34 @@ class _ImageThumbShape extends SliderComponentShape {
final stream = image.resolve(ImageConfiguration()); final stream = image.resolve(ImageConfiguration());
// //
stream.addListener(ImageStreamListener((imageInfo, _) { stream.addListener(
final rect = Rect.fromCenter( ImageStreamListener(
center: center, (imageInfo, _) {
width: imageSize, final rect = Rect.fromCenter(
height: imageSize, center: center,
); width: imageSize,
context.canvas.drawImageRect( height: imageSize,
imageInfo.image, );
Rect.fromLTWH( context.canvas.drawImageRect(
0, imageInfo.image,
0, Rect.fromLTWH(
imageInfo.image.width.toDouble(), 0,
imageInfo.image.height.toDouble(), 0,
), imageInfo.image.width.toDouble(),
rect, imageInfo.image.height.toDouble(),
Paint(), ),
); rect,
}, onError: (error, stackTrace) { Paint(),
// 🔥 );
final paint = Paint() },
..color = Colors.white onError: (error, stackTrace) {
..style = PaintingStyle.fill; // 🔥
context.canvas.drawCircle(center, imageSize / 2, paint); final paint = Paint()
})); ..color = Colors.white
..style = PaintingStyle.fill;
context.canvas.drawCircle(center, imageSize / 2, paint);
},
),
);
} }
} }

View File

@ -6,6 +6,7 @@ import 'package:skywood/pages/like/widget/like_header.dart';
import 'package:skywood/pages/widgets/common_bg_page.dart'; import 'package:skywood/pages/widgets/common_bg_page.dart';
import 'package:skywood/pages/widgets/pixel_widgets.dart'; import 'package:skywood/pages/widgets/pixel_widgets.dart';
import 'package:skywood/utils/extend/app_keep_alive.dart'; import 'package:skywood/utils/extend/app_keep_alive.dart';
import 'package:skywood/utils/tools/app_sp.dart';
class LikePage extends StatefulWidget { class LikePage extends StatefulWidget {
const LikePage({super.key}); const LikePage({super.key});
@ -17,17 +18,21 @@ class LikePage extends StatefulWidget {
} }
class _MainRootState extends State<LikePage> { class _MainRootState extends State<LikePage> {
int _tabIndex = 0; PageController _pageController = PageController(initialPage: 0);
final _pageController = PageController(initialPage: 0); int _currentIndex = 0;
static const String _keyIndex = 'LIKE_PAGE_INDEX';
final List<String> _collectionTitles = const [ @override
'Undercover Play', void initState() {
"Don't Cross Me", super.initState();
'Two Worlds Apart', _loadInitIndex();
'Rekindled Scorn',
'My Revenge is You',
"Mr. Gu's Sweet Weakness", }
];
_loadInitIndex() async {
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -35,7 +40,10 @@ class _MainRootState extends State<LikePage> {
child: SafeArea( child: SafeArea(
bottom: false, bottom: false,
child: Padding( child: Padding(
padding: EdgeInsets.only(left: 15.w, right: 15.w, top: 20.h, bottom: 10.h+50.h), padding: EdgeInsets.only(left: 15.w, right: 15.w,
top: AppScreen.isIos ? 0 : 20.h,
bottom: (AppScreen.isIos ? 30.h : 10.h)+50.h
),
child: Stack( child: Stack(
children: [ children: [
HelpImg.asset(ConstImg.likeBg, width: AppScreen.screenWidth - 30.w, height: 700.h, HelpImg.asset(ConstImg.likeBg, width: AppScreen.screenWidth - 30.w, height: 700.h,
@ -48,8 +56,10 @@ class _MainRootState extends State<LikePage> {
Padding( Padding(
padding: const EdgeInsets.only(left: 10, top: 10), padding: const EdgeInsets.only(left: 10, top: 10),
child: LikeHeader( child: LikeHeader(
initIndex: _currentIndex,
onSelectedIndex: (index) { onSelectedIndex: (index) {
_pageController.jumpToPage(index); _pageController.jumpToPage(index);
_currentIndex = index;
}, },
), ),
), ),
@ -58,8 +68,10 @@ class _MainRootState extends State<LikePage> {
child: PageView( child: PageView(
controller: _pageController, controller: _pageController,
children: [ children: [
AppKeepAlive(child: CollectionPage()), CollectionPage(),
AppKeepAlive(child: PlayLogPage()) PlayLogPage()
// AppKeepAlive(child: CollectionPage()),
// AppKeepAlive(child: PlayLogPage())
], ],
), ),
) )
@ -71,315 +83,5 @@ class _MainRootState extends State<LikePage> {
)), )),
); );
} }
Widget _buildTabs() {
return Row(
children: [
Expanded(
child: _LibraryTab(
title: 'My Collection',
selected: _tabIndex == 0,
onTap: () => setState(() => _tabIndex = 0),
),
),
SizedBox(width: 8.w),
Expanded(
child: _LibraryTab(
title: 'Play Log',
selected: _tabIndex == 1,
onTap: () => setState(() => _tabIndex = 1),
),
),
],
);
}
Widget _buildCollection() {
return GridView.builder(
key: const ValueKey('collection'),
padding: EdgeInsets.only(top: 2.h, bottom: 120.h),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10.h,
crossAxisSpacing: 7.w,
childAspectRatio: 100 / 174,
),
itemCount: _collectionTitles.length,
itemBuilder: (context, index) {
return _CollectionCard(title: _collectionTitles[index]);
},
);
}
Widget _buildPlayLog() {
return ListView(
key: const ValueKey('play-log'),
padding: EdgeInsets.only(bottom: 120.h),
children: [
_ContinueCard(),
SizedBox(height: 18.h),
Text(
'Watch History',
style: TextStyle(
color: const Color(0xFF1C1E1F),
fontSize: 16.sp,
fontWeight: FontWeight.w700,
height: 1,
),
),
SizedBox(height: 10.h),
_HistoryItem(title: 'As A Mafia Boss, I Refuse To Be An Extra'),
SizedBox(height: 10.h),
_HistoryItem(title: 'Fatal Vengeance'),
SizedBox(height: 10.h),
_HistoryItem(title: "Don't Cross Me"),
],
);
}
} }
class _LibraryTab extends StatelessWidget {
const _LibraryTab({
required this.title,
required this.selected,
required this.onTap,
});
final String title;
final bool selected;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
height: 45.h,
alignment: Alignment.center,
decoration: BoxDecoration(
color: selected ? const Color(0xFF16ED1E) : const Color(0xFFF6F6F6),
border: Border.all(
color: selected ? CommonColor.black : const Color(0xFFD6D6D6),
width: 1.5.w,
),
boxShadow: selected
? const [
BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(2, 2)),
]
: null,
),
child: Text(
title,
style: TextStyle(
color: selected ? Colors.white : const Color(0xFFB2B2B2),
fontSize: 14.sp,
fontWeight: FontWeight.w900,
height: 1,
shadows: selected
? const [Shadow(color: Color(0xFF1C1E1F), offset: Offset(1, 1))]
: null,
),
),
),
);
}
}
class _CollectionCard extends StatelessWidget {
const _CollectionCard({required this.title});
final String title;
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.fromLTRB(4.w, 8.h, 4.w, 6.h),
decoration: BoxDecoration(
color: const Color(0xFFF4FFB6),
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
boxShadow: const [
BoxShadow(color: Color(0xFF653CFA), offset: Offset(3, 3)),
],
),
child: Column(
children: [
Row(
children: List.generate(4, (index) {
return Container(
width: 11.w,
height: 6.h,
margin: EdgeInsets.only(right: 5.w),
decoration: BoxDecoration(
color: index == 3
? const Color(0xFFEAEAEA)
: const Color(0xFF96FE9B),
border: Border.all(
color: const Color(0xFF1C1E1F),
width: 0.8.w,
),
),
);
}),
),
SizedBox(height: 8.h),
const Expanded(child: PosterImage()),
SizedBox(height: 8.h),
Text(
title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: const Color(0xFF1C1E1F),
fontSize: 13.sp,
fontWeight: FontWeight.w500,
height: 1,
),
),
],
),
);
}
}
class _ContinueCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 140.h,
padding: EdgeInsets.all(10.w),
decoration: BoxDecoration(
color: const Color(0xFFEAE6FF),
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
),
child: Row(
children: [
const PosterImage(width: 90, height: 120, borderRadius: 2),
SizedBox(width: 10.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Mogul And His Runaway Bride',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: const Color(0xFF1B1926),
fontSize: 14.sp,
fontWeight: FontWeight.w600,
height: 1.25,
),
),
SizedBox(height: 18.h),
Text(
'Chapter 10 / 28',
style: TextStyle(
color: CommonColor.primacyColor,
fontSize: 11.sp,
height: 1,
),
),
SizedBox(height: 6.h),
_ProgressLine(value: 0.46),
const Spacer(),
const PixelButton(
label: 'Continue Watch',
width: 145,
height: 29,
),
],
),
),
],
),
);
}
}
class _HistoryItem extends StatelessWidget {
const _HistoryItem({required this.title});
final String title;
@override
Widget build(BuildContext context) {
return Container(
height: 100.h,
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 6.h),
decoration: BoxDecoration(
color: const Color(0xFFEAE6FF),
border: Border.all(color: const Color(0xFF1C1E1F), width: 1.w),
),
child: Row(
children: [
const PosterImage(width: 66, height: 88, borderRadius: 2),
SizedBox(width: 10.w),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: CommonColor.black,
fontSize: 13.sp,
fontWeight: FontWeight.w600,
height: 1.2,
),
),
Text(
'EP.40/85',
style: TextStyle(
color: CommonColor.primacyColor,
fontSize: 11.sp,
height: 1,
),
),
_ProgressLine(value: 0.46),
],
),
),
],
),
);
}
}
class _ProgressLine extends StatelessWidget {
const _ProgressLine({required this.value});
final double value;
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: Container(
height: 6.h,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.7),
border: Border.all(color: const Color(0xFF1C1E1F), width: 0.5.w),
borderRadius: BorderRadius.circular(10.r),
),
alignment: Alignment.centerLeft,
child: FractionallySizedBox(
widthFactor: value,
child: Container(
decoration: BoxDecoration(
color: const Color(0xFF00EE02),
borderRadius: BorderRadius.circular(10.r),
),
),
),
),
),
SizedBox(width: 4.w),
Text('46%', style: TextStyle(fontSize: 10.sp, height: 1)),
],
);
}
}

View File

@ -2,7 +2,9 @@ import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart'; import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/page/drama_detail_page.dart'; import 'package:skywood/pages/home/players/page/drama_detail_page.dart';
import 'package:skywood/pages/like/widget/no_data_view.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart'; import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/tools/app_toast.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart'; import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
class CollectionPage extends StatefulWidget { class CollectionPage extends StatefulWidget {
@ -18,6 +20,7 @@ class CollectionPage extends StatefulWidget {
class _CollectionPageState extends State<CollectionPage> { class _CollectionPageState extends State<CollectionPage> {
List<SkywoodDrama> _collectionList = []; List<SkywoodDrama> _collectionList = [];
bool _isLoading = false;
@override @override
void initState() { void initState() {
@ -26,7 +29,12 @@ class _CollectionPageState extends State<CollectionPage> {
} }
void _getCollection() { void _getCollection() {
_isLoading = true;
AppToast.showLottieLoading();
PlayClient.getCollections().then((value) { PlayClient.getCollections().then((value) {
_isLoading = false;
AppToast.dismiss();
if (!mounted) return;
setState(() { setState(() {
_collectionList = value; _collectionList = value;
}); });
@ -35,7 +43,7 @@ class _CollectionPageState extends State<CollectionPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GridView.builder( return !_isLoading&&_collectionList.isEmpty ? NoDataView() : GridView.builder(
padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 10.h), padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 10.h),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, crossAxisCount: 3,

View File

@ -1,8 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart'; import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/page/drama_detail_page.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart'; import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
import '../../../utils/tools/app_toast.dart';
import '../widget/no_data_view.dart';
class PlayLogPage extends StatefulWidget { class PlayLogPage extends StatefulWidget {
const PlayLogPage({super.key}); const PlayLogPage({super.key});
@ -15,6 +20,9 @@ class PlayLogPage extends StatefulWidget {
class _CollectionPageState extends State<PlayLogPage> { class _CollectionPageState extends State<PlayLogPage> {
List<SkywoodDrama> _historyList = [];
bool _isLoading = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -22,16 +30,25 @@ class _CollectionPageState extends State<PlayLogPage> {
} }
void _getHistory() { void _getHistory() {
PlayClient.getHistory().then((value) {}); _isLoading = true;
AppToast.showLottieLoading();
PlayClient.getHistory().then((value) {
_isLoading = false;
AppToast.dismiss();
setState(() {
_historyList = value;
});
});
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListView.separated( return !_isLoading&&_historyList.isEmpty ? NoDataView() : ListView.separated(
padding: const EdgeInsets.only(top: 20, left: 12, right: 12), padding: const EdgeInsets.only(top: 20, left: 12, right: 12),
itemCount: 5, itemCount: _historyList.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return index == 0 ? _buildFirstItem() : _buildNormalItem(); final item = _historyList[index];
return index == 0 ? _buildFirstItem(item) : _buildNormalItem(item);
}, },
separatorBuilder: (context, index) { separatorBuilder: (context, index) {
return SizedBox(height: 5); return SizedBox(height: 5);
@ -39,25 +56,103 @@ class _CollectionPageState extends State<PlayLogPage> {
); );
} }
Widget _buildNormalItem() { Widget _buildNormalItem(SkywoodDrama item) {
return Stack( return Stack(
children: [ children: [
HelpImg.asset(ConstImg.playlogBg, width: double.infinity, height: 90, fit: BoxFit.fill), HelpImg.asset(ConstImg.playlogBg, width: double.infinity, height: 100, fit: BoxFit.fill),
_ProgressLine(value: 0.2) Positioned(
left: 10, top: 5, right: 5, bottom: 5,
child: Row(
children: [
HelpImg.network(item.imageUrl, width: 66, height: 88, fit: BoxFit.fill),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 6),
Expanded(child: SizedBox(
width: 192.w,
child: SkyText(text: item.name,
fontSize: 14,
fontWeight: FontWeight.bold,
color: CommonColor.black,
maxLines: 2,
),
)),
SkyText(text: 'EP.${item.currentEpisode} / ${item.episodeTotal}',
fontSize: 11,
color: CommonColor.primacyColor,
),
const SizedBox(height: 5),
_ProgressLine(value: (item.currentEpisode ?? 1) / item.episodeTotal, width: 150,),
const SizedBox(height: 10),
],
)
],
),
)
],
).addInkWell(onTap: () {
HelpNav.to(DramaDetailPage(dramaBean: item));
});
}
Widget _buildFirstItem(SkywoodDrama item) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildFirstCard(item),
const SizedBox(height: 20),
if (_historyList.length > 1)
SkyText(text: 'Watch History',
color: CommonColor.black,
fontSize: 16,
fontWeight: FontWeight.bold,
)
], ],
); );
} }
Widget _buildFirstItem() { Widget _buildFirstCard(SkywoodDrama item) {
return Column( return Stack(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
HelpImg.asset(ConstImg.playlogBg, width: double.infinity, height: 140, fit: BoxFit.fill), HelpImg.asset(ConstImg.playlogBg, width: 297.w, height: 140, fit: BoxFit.fill),
const SizedBox(height: 20), Positioned(
SkyText(text: 'Watch History', left: 10, top: 5, right: 5, bottom: 5,
color: CommonColor.black, child: Row(
fontSize: 16, children: [
fontWeight: FontWeight.bold, HelpImg.network(item.imageUrl, width: 90, height: 120, fit: BoxFit.fill),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 6),
Expanded(child: SizedBox(
width: 170.w,
child: SkyText(text: item.name,
fontSize: 14,
fontWeight: FontWeight.bold,
color: CommonColor.black,
maxLines: 2,
),
)),
SkyText(text: 'Chapter ${item.currentEpisode} / ${item.episodeTotal}',
fontSize: 11,
color: CommonColor.primacyColor,
),
const SizedBox(height: 5),
_ProgressLine(value: (item.currentEpisode ?? 1) / item.episodeTotal, width: 150,),
const SizedBox(height: 10),
HelpImg.asset(ConstImg.continueWatch, width: 144, height: 30).addInkWell(
onTap: () {
HelpNav.to(DramaDetailPage(dramaBean: item));
}
),
const SizedBox(height: 8),
],
)
],
),
) )
], ],
); );
@ -67,37 +162,44 @@ class _CollectionPageState extends State<PlayLogPage> {
class _ProgressLine extends StatelessWidget { class _ProgressLine extends StatelessWidget {
const _ProgressLine({required this.value}); const _ProgressLine({
required this.value,
this.width = 140,
});
final double value; final double value;
final double width;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return SizedBox(
children: [ width: width,
Expanded( child: Row(
child: Container( children: [
height: 6.h, Expanded(
decoration: BoxDecoration( child: Container(
color: Colors.white.withValues(alpha: 0.7), height: 6.h,
border: Border.all(color: const Color(0xFF1C1E1F), width: 0.5.w), decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.r), color: Colors.white.withValues(alpha: 0.7),
), border: Border.all(color: const Color(0xFF1C1E1F), width: 0.5.w),
alignment: Alignment.centerLeft, borderRadius: BorderRadius.circular(10.r),
child: FractionallySizedBox( ),
widthFactor: value, alignment: Alignment.centerLeft,
child: Container( child: FractionallySizedBox(
decoration: BoxDecoration( widthFactor: value,
color: const Color(0xFF00EE02), child: Container(
borderRadius: BorderRadius.circular(10.r), decoration: BoxDecoration(
color: const Color(0xFF00EE02),
borderRadius: BorderRadius.circular(10.r),
),
), ),
), ),
), ),
), ),
), SizedBox(width: 4.w),
SizedBox(width: 4.w), Text('${(value * 100.0).toInt()}%', style: TextStyle(fontSize: 10.sp, height: 1)),
Text('${(value * 100.0).toInt()}%', style: TextStyle(fontSize: 10.sp, height: 1)), ],
], ),
); );
} }
} }

View File

@ -6,9 +6,11 @@ class LikeHeader extends StatefulWidget {
const LikeHeader({super.key, const LikeHeader({super.key,
required this.onSelectedIndex, required this.onSelectedIndex,
required this.initIndex,
}); });
final Function(int) onSelectedIndex; final Function(int) onSelectedIndex;
final int initIndex;
@override @override
State<StatefulWidget> createState() { State<StatefulWidget> createState() {
@ -20,6 +22,18 @@ class _LikeHeaderState extends State<LikeHeader> {
int _selectedIndex = 0; int _selectedIndex = 0;
@override
void initState() {
super.initState();
if (widget.initIndex != 0) {
if (!mounted) return;
setState(() {
_selectedIndex = widget.initIndex;
});
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return SizedBox(

View File

@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import 'package:skywood/main/lib_file.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
class NoDataView extends StatelessWidget {
const NoDataView({super.key,
this.title = 'No Data',
// 'Nothing here yet.\nCome back later for more fun!',
// Something went wrong.\nPlease try again.
this.subtitle = 'Nothing here yet.\nCome back later for more fun!',
this.btnText = 'RETRY',
this.imgName,
this.onTap,
});
final String title;
final String subtitle;
final String btnText;
final String? imgName;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 100),
HelpImg.asset(ConstImg.nodataImg, width: 136),
const SizedBox(height: 14),
_customText(title),
const SizedBox(height: 10),
SkyText(text: subtitle, maxLines: 2,
fontSize: 14,
color: CommonColor.black,
textAlign: TextAlign.center,
),
const SizedBox(height: 14),
if (onTap != null)
InkWell(
onTap: onTap,
child: Stack(
children: [
HelpImg.asset(imgName ?? ConstImg.btnBg, width: 140, height: 46, fit: BoxFit.fill,),
Positioned.fill(
child: Center(
child: SkyText(text: btnText, color: Colors.white),
),
)
],
)
)
],
),
);
}
_customText(String text) {
return Text(
text,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: Colors.white, //
fontStyle: FontStyle.italic,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
shadows: [
Shadow(
color: Colors.black, //
offset: Offset(1, 1), //
blurRadius: 0, //
),
Shadow(
color: Colors.black,
offset: Offset(-1, -1),
blurRadius: 0,
),
Shadow(
color: Colors.black,
offset: Offset(1, -1),
blurRadius: 0,
),
Shadow(
color: Colors.black,
offset: Offset(-1, 1),
blurRadius: 0,
),
],
),
);
}
}

View File

@ -4,6 +4,7 @@ import 'package:skywood/global/client/user_client.dart';
import 'package:skywood/global/request/api_const.dart'; import 'package:skywood/global/request/api_const.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/mine/page/about_us_page.dart'; import 'package:skywood/pages/mine/page/about_us_page.dart';
import 'package:skywood/pages/mine/page/mine_collection_page.dart';
import 'package:skywood/pages/mine/page/sky_web_page.dart'; import 'package:skywood/pages/mine/page/sky_web_page.dart';
import 'package:skywood/pages/mine/widget/mine_section_view.dart'; import 'package:skywood/pages/mine/widget/mine_section_view.dart';
import 'package:skywood/pages/widgets/pixel_widgets.dart'; import 'package:skywood/pages/widgets/pixel_widgets.dart';
@ -28,6 +29,12 @@ class _MainRootState extends State<MinePage> {
List<Widget> _buildSections() { List<Widget> _buildSections() {
final menuData = [ final menuData = [
{
'title': 'Collection', 'img': ConstImg.collection,
'action': () {
HelpNav.to(MineCollectionPage());
}
},
{ {
'title': 'Privacy Policy', 'img': ConstImg.minePp, 'title': 'Privacy Policy', 'img': ConstImg.minePp,
'action': () { 'action': () {
@ -168,10 +175,11 @@ class _MainRootState extends State<MinePage> {
child: Column( child: Column(
children: [ children: [
HelpImg.asset(imgName, width: _w/2.0), HelpImg.asset(imgName, width: _w/2.0),
SkyText(text: title, fontSize: 9, color: Colors.white, const SizedBox(height: 2),
SkyText(text: title, fontSize: 9.w, color: Colors.white,
maxLines: 2, maxLines: 2,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), )
], ],
), ),
) )
@ -181,70 +189,3 @@ class _MainRootState extends State<MinePage> {
} }
class _MenuTile extends StatelessWidget {
const _MenuTile({required this.item});
final _MenuItem item;
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.fromLTRB(4.w, 4.h, 4.w, 6.h),
decoration: BoxDecoration(
color: const Color(0xFF8D62F7),
border: Border.all(color: CommonColor.black, width: 1.w),
boxShadow: const [
BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(2, 2)),
],
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(item.icon, color: Colors.white, size: 25.w),
SizedBox(height: 5.h),
Text(
item.label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontSize: 8.sp,
fontWeight: FontWeight.w700,
height: 1,
),
),
],
),
);
}
}
class _DecorIcon extends StatelessWidget {
const _DecorIcon({required this.icon, required this.color});
final IconData icon;
final Color color;
@override
Widget build(BuildContext context) {
return Container(
width: 50.w,
height: 50.w,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: CommonColor.black, width: 1.w),
boxShadow: const [
BoxShadow(color: Color(0xFF1C1E1F), offset: Offset(2, 2)),
],
),
child: Icon(icon, color: color, size: 32.w),
);
}
}
class _MenuItem {
const _MenuItem(this.label, this.icon);
final String label;
final IconData icon;
}

View File

@ -1,6 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/global/const/common_color.dart';
import 'package:skywood/global/request/api_const.dart'; import 'package:skywood/global/request/api_const.dart';
import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/mine/page/sky_web_page.dart';
import 'package:skywood/utils/tools/sky_device_info.dart'; import 'package:skywood/utils/tools/sky_device_info.dart';
import 'package:skywood/utils/tools/widgets/sky_app_bar.dart'; import 'package:skywood/utils/tools/widgets/sky_app_bar.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart'; import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
@ -14,14 +17,19 @@ class AboutUsPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: SkyAppBar( appBar: SkyAppBar(
title: 'About Us', title: 'About',
), ),
body: SizedBox( body: SizedBox(
width: double.infinity, width: double.infinity,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
const SizedBox(height: 100), const SizedBox(height: 50),
SizedBox(
width: 80, height: 80,
child: HelpImg.asset(ConstImg.appLogo),
),
const SizedBox(height: 10),
SkyText(text: ApiConst.appName, SkyText(text: ApiConst.appName,
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -33,20 +41,55 @@ class AboutUsPage extends StatelessWidget {
color: Colors.grey, color: Colors.grey,
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
Container( _buildRowItem('Privacy Policy', () {
height: 46, HelpNav.to(SkyWebPage(params: WebLinkParams(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 4), title: 'Privacy Policy',
child: Row( urlString: ApiConst.webPrivacy,
children: [ )));
}),
_buildRowItem('User Agreement', () {
HelpNav.to(SkyWebPage(params: WebLinkParams(
title: 'User Agreement',
urlString: ApiConst.webAgreement,
)));
}),
_buildRowItem('Visit Website', () async {
final encodedUrl = Uri.encodeFull(ApiConst.webIndex);
try {
final bool launched = await launchUrl(
Uri.parse(encodedUrl),
mode: LaunchMode.externalApplication,
);
if (!launched) {
print('无法打开链接: $encodedUrl');
}
} catch (e) {
print('打开链接异常: $e');
}
}),
],
),
)
], ],
), ),
), ),
); );
} }
_buildRowItem(String title, Function() onTap) {
return Container(
height: 46,
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
margin: const EdgeInsets.only(bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SkyText(text: title, fontSize: 14, color: Colors.black),
Icon(Icons.arrow_forward, color: CommonColor.black, size: 18,),
],
),
).addInkWell(onTap: onTap);
}
Future<void> openUrl(String url) async { Future<void> openUrl(String url) async {
final encodedUrl = Uri.encodeFull(url); final encodedUrl = Uri.encodeFull(url);

View File

@ -0,0 +1,147 @@
import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/page/drama_detail_page.dart';
import 'package:skywood/pages/like/widget/no_data_view.dart';
import 'package:skywood/pages/search/page/result_page.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/tools/app_toast.dart';
import 'package:skywood/utils/tools/widgets/sky_app_bar.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
import '../../../utils/tools/sky_time_tool.dart';
class MineCollectionPage extends StatefulWidget {
const MineCollectionPage({super.key});
@override
State<StatefulWidget> createState() {
return _CollectionPageState();
}
}
class _CollectionPageState extends State<MineCollectionPage> {
List<SkywoodDrama> _collectionList = [];
bool _isLoading = false;
@override
void initState() {
super.initState();
_getCollection();
}
void _getCollection() {
AppToast.showLottieLoading();
_isLoading = true;
PlayClient.getCollections().then((value) {
AppToast.dismiss();
_isLoading = false;
if (!mounted) return;
setState(() {
_collectionList = value;
});
});
}
void _cancelCol(int shortPlayId) {
// AppToast.showLottieLoading();
// remove
_collectionList.removeWhere((element) => element.shortPlayId == shortPlayId);
PlayClient.cancelCollect(shortPlayId: shortPlayId).then((value) {
// AppToast.dismiss();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: SkyAppBar(
title: 'Collection',
actions: [],
),
body: !_isLoading && _collectionList.isEmpty ? NoDataView() : ListView.separated(
itemBuilder: (context, index) {
final item = _collectionList[index];
return Dismissible(
onDismissed: (direction) {
_cancelCol(item.shortPlayId!);
},
key: Key(item.shortPlayId.toString()),
child: MineItemView(drama: _collectionList[index]),
);
},
separatorBuilder: (context, index) {
return const SizedBox(height: 5);
},
itemCount: _collectionList.length
),
);
}
}
class MineItemView extends StatelessWidget {
const MineItemView({super.key,
required this.drama,
this.onTap
});
final SkywoodDrama drama;
final Function()? onTap;
@override
Widget build(BuildContext context) {
return Container(
height: 120.h,
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Row(
children: [
HelpImg.networkRadius(drama.imageUrl, width: 90.w, height: 110.h,
borderRadius: BorderRadius.circular(6),
fit: BoxFit.cover,
),
const SizedBox(width: 10),
Expanded(child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 8),
SkyText(text: drama.name,
fontSize: 14,
fontWeight: FontWeight.bold,
color: CommonColor.black,
),
const SizedBox(height: 12),
SkyText(text: drama.description,
fontSize: 11,
color: CommonColor.withValue('4D4047'),
maxLines: 2,
),
Spacer(),
_tipView(true, text: 'EP.${drama.episodeTotal}'),
const SizedBox(height: 10),
],
))
],
),
).addInkWell(onTap: onTap);
}
Widget _tipView(bool isStar, {required String text}) {
String imgName = isStar ? ConstImg.star : ConstImg.look;
return Row(
children: [
HelpImg.asset(imgName, width: 12.w, height: 12.w),
const SizedBox(width: 2),
SkyText(text: text, fontSize: 12, color: Colors.grey)
],
);
}
}

View File

@ -1,9 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:skywood/global/const/common_color.dart';
import 'package:skywood/utils/tools/widgets/sky_app_bar.dart'; import 'package:skywood/utils/tools/widgets/sky_app_bar.dart';
import 'package:webview_flutter/webview_flutter.dart'; import 'package:webview_flutter/webview_flutter.dart';
import '../../../utils/tools/help_img.dart';
/// WebView /// WebView
class WebLinkParams { class WebLinkParams {
final String title; final String title;
@ -212,7 +215,7 @@ class _WebLinkViewState extends State<SkyWebPage> {
titleColor: Colors.white, titleColor: Colors.white,
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.refresh), icon: const Icon(Icons.refresh, color: Colors.white,),
onPressed: _reload, onPressed: _reload,
), ),
], ],
@ -221,12 +224,12 @@ class _WebLinkViewState extends State<SkyWebPage> {
Widget _buildBody() { Widget _buildBody() {
return Container( return Container(
decoration: const BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [ colors: [
Color(0xFF1A0B2E), CommonColor.primacyColor,
Color(0xFF2D1B4E), Color(0xFF2D1B4E),
], ],
), ),
@ -255,9 +258,10 @@ class _WebLinkViewState extends State<SkyWebPage> {
Widget _buildContent() { Widget _buildContent() {
if (_isLoading) { if (_isLoading) {
return Center( return Center(
child: LoadingAnimationWidget.newtonCradle( child: SizedBox(
color: const Color(0xFFFB98E0), width: 120,
size: 96.w, height: 120,
child: Image.asset(ConstImg.loading, fit: BoxFit.fill),
), ),
); );
} }

View File

@ -49,7 +49,7 @@ class MineSectionView extends StatelessWidget {
children: [ children: [
HelpImg.asset(ConstImg.sectionTopBg, width: width, height: 20.h), HelpImg.asset(ConstImg.sectionTopBg, width: width, height: 20.h),
Positioned( Positioned(
left: 7, right: 7, left: 7, right: 7, top: 2,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [

View File

@ -4,11 +4,13 @@ import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/page/drama_detail_page.dart'; import 'package:skywood/pages/home/players/page/drama_detail_page.dart';
import 'package:skywood/pages/widgets/pixel_widgets.dart'; import 'package:skywood/pages/widgets/pixel_widgets.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart'; import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/tools/app_toast.dart';
import 'package:skywood/utils/tools/sky_time_tool.dart'; import 'package:skywood/utils/tools/sky_time_tool.dart';
import 'package:skywood/utils/tools/widgets/sky_app_bar.dart'; import 'package:skywood/utils/tools/widgets/sky_app_bar.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart'; import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
import '../../../utils/tools/widgets/sky_text_field.dart'; import '../../../utils/tools/widgets/sky_text_field.dart';
import '../../like/widget/no_data_view.dart';
import '../widget/search_util.dart'; import '../widget/search_util.dart';
class ResultPage extends StatefulWidget { class ResultPage extends StatefulWidget {
@ -30,6 +32,7 @@ class _ResultPageState extends State<ResultPage> {
final _searchController = TextEditingController(); final _searchController = TextEditingController();
final _searchFocus = FocusNode(); final _searchFocus = FocusNode();
List<SkywoodDrama> _searchResult = []; List<SkywoodDrama> _searchResult = [];
bool _isLoading = false;
@override @override
void initState() { void initState() {
@ -45,8 +48,12 @@ class _ResultPageState extends State<ResultPage> {
_searchFocus.requestFocus(); _searchFocus.requestFocus();
return; return;
} }
_isLoading = true;
AppToast.showLottieLoading();
await SearchUtil.addSearch(keyword); await SearchUtil.addSearch(keyword);
PlayClient.search(keyword: keyword).then((valuer) { PlayClient.search(keyword: keyword).then((valuer) {
_isLoading = false;
AppToast.dismiss();
setState(() { setState(() {
_searchResult = valuer; _searchResult = valuer;
}); });
@ -74,7 +81,7 @@ class _ResultPageState extends State<ResultPage> {
}, },
), ),
), ),
body: ListView.separated( body: _searchResult.isEmpty && !_isLoading ? NoDataView() : ListView.separated(
itemBuilder: (context, index) => ResultItemView( itemBuilder: (context, index) => ResultItemView(
drama: _searchResult[index], drama: _searchResult[index],
onTap: () { onTap: () {
@ -111,6 +118,7 @@ class ResultItemView extends StatelessWidget {
children: [ children: [
HelpImg.networkRadius(drama.imageUrl, width: 105.w, height: 140.h, HelpImg.networkRadius(drama.imageUrl, width: 105.w, height: 140.h,
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
fit: BoxFit.cover,
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
Expanded(child: Column( Expanded(child: Column(

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:skywood/main/lib_file.dart'; import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/page/drama_detail_page.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart'; import 'package:skywood/utils/models/drama/skywood_drama.dart';
class MysteryBoxWidget extends StatelessWidget { class MysteryBoxWidget extends StatelessWidget {
@ -16,7 +15,7 @@ class MysteryBoxWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SizedBox( return SizedBox(
width: AppScreen.screenWidth, height: 400, width: AppScreen.screenWidth, height: 450,
child: Column( child: Column(
children: [ children: [
HelpImg.asset(ConstImg.boxOpened, width: 179, height: 24), HelpImg.asset(ConstImg.boxOpened, width: 179, height: 24),
@ -42,7 +41,11 @@ class MysteryBoxWidget extends StatelessWidget {
HelpNav.back(); HelpNav.back();
onTap?.call(); onTap?.call();
} }
) ),
const SizedBox(height: 12),
IconButton(onPressed: () {
HelpNav.back();
}, icon: HelpImg.asset(ConstImg.boxClose, width: 30))
], ],
), ),
); );

View File

@ -5,7 +5,7 @@ import 'package:shared_preferences/shared_preferences.dart';
// AppSp().setString("key", "value"); // AppSp().setString("key", "value");
class AppSp { class AppSp {
static SharedPreferences? _instance; static SharedPreferences? _instance;
static final String _basePrefix = "omiyo."; static final String _basePrefix = "app.";
static Future<SharedPreferences>? _instanceFuture; static Future<SharedPreferences>? _instanceFuture;
static Future<SharedPreferences> getInstance() { static Future<SharedPreferences> getInstance() {

View File

@ -17,6 +17,14 @@ class ConstImg {
static const String tabMineUnselect = "assets/common/tab_mine_unselect.png"; static const String tabMineUnselect = "assets/common/tab_mine_unselect.png";
// loading // loading
static const String loading = "assets/common/loading.gif"; static const String loading = "assets/common/loading.gif";
static const String btnBg = "assets/common/btn_bg.png";
static const String noData = "assets/common/no_data.png";
static const String nodataImg = "assets/common/nodata_img.png";
static const String noworkImg = "assets/common/nowork_img.png";
// applogo
static const String appLogo = "assets/common/applogo.png";
static const String homeBg = "assets/imgs/home_bg.png"; static const String homeBg = "assets/imgs/home_bg.png";
// home_card_bg // home_card_bg
@ -91,10 +99,9 @@ class ConstImg {
static const String mineAb = "assets/mine/mine_ab.png"; static const String mineAb = "assets/mine/mine_ab.png";
static const String minePp = "assets/mine/mine_pp.png"; static const String minePp = "assets/mine/mine_pp.png";
static const String mineUa = "assets/mine/mine_ua.png"; static const String mineUa = "assets/mine/mine_ua.png";
static const String collection = "assets/mine/collection.png";
// nodata
static const String noData = "assets/images/nodata.png";
static const String loadingJson = "assets/bagua.json"; static const String loadingJson = "assets/bagua.json";
// static get appLoading => Lottie.asset(loadingJson, width: 60, height: 60); // static get appLoading => Lottie.asset(loadingJson, width: 60, height: 60);
@ -180,15 +187,18 @@ class HelpImg {
fit: fit, fit: fit,
loadingBuilder: (context, child, loadingProgress) { loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child; if (loadingProgress == null) return child;
return Center( return SizedBox(
//CircularProgressIndicator width: width, height: height,
child: Container( child: Center(
width: 50, //CircularProgressIndicator
height: 50, child: Container(
padding: const EdgeInsets.all(5), width: 30,
child: CircularProgressIndicator( height: 30,
color: Colors.white, padding: const EdgeInsets.all(5),
strokeWidth: 2, child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 1,
),
), ),
), ),
); );