Merge pull request #24 from krawieck/full-post
This commit is contained in:
commit
83ce411db4
|
@ -0,0 +1 @@
|
||||||
|
20ad19f2b9a812ac7774ca58ddf04b2e
|
|
@ -1 +1,2 @@
|
||||||
|
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
#include "Generated.xcconfig"
|
#include "Generated.xcconfig"
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
|
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
#include "Generated.xcconfig"
|
#include "Generated.xcconfig"
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Uncomment this line to define a global platform for your project
|
||||||
|
# platform :ios, '9.0'
|
||||||
|
|
||||||
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|
||||||
|
project 'Runner', {
|
||||||
|
'Debug' => :debug,
|
||||||
|
'Profile' => :release,
|
||||||
|
'Release' => :release,
|
||||||
|
}
|
||||||
|
|
||||||
|
def flutter_root
|
||||||
|
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||||
|
unless File.exist?(generated_xcode_build_settings_path)
|
||||||
|
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||||
|
end
|
||||||
|
|
||||||
|
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||||
|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||||
|
return matches[1].strip if matches
|
||||||
|
end
|
||||||
|
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||||
|
end
|
||||||
|
|
||||||
|
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||||
|
|
||||||
|
flutter_ios_podfile_setup
|
||||||
|
|
||||||
|
target 'Runner' do
|
||||||
|
use_frameworks!
|
||||||
|
use_modular_headers!
|
||||||
|
|
||||||
|
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||||
|
end
|
||||||
|
|
||||||
|
post_install do |installer|
|
||||||
|
installer.pods_project.targets.each do |target|
|
||||||
|
flutter_additional_ios_build_settings(target)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,55 @@
|
||||||
|
PODS:
|
||||||
|
- esys_flutter_share (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- Flutter (1.0.0)
|
||||||
|
- FMDB (2.7.5):
|
||||||
|
- FMDB/standard (= 2.7.5)
|
||||||
|
- FMDB/standard (2.7.5)
|
||||||
|
- path_provider (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- shared_preferences (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- sqflite (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FMDB (~> 2.7.2)
|
||||||
|
- url_launcher (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
|
||||||
|
- Flutter (from `Flutter`)
|
||||||
|
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||||
|
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||||
|
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||||
|
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
||||||
|
|
||||||
|
SPEC REPOS:
|
||||||
|
trunk:
|
||||||
|
- FMDB
|
||||||
|
|
||||||
|
EXTERNAL SOURCES:
|
||||||
|
esys_flutter_share:
|
||||||
|
:path: ".symlinks/plugins/esys_flutter_share/ios"
|
||||||
|
Flutter:
|
||||||
|
:path: Flutter
|
||||||
|
path_provider:
|
||||||
|
:path: ".symlinks/plugins/path_provider/ios"
|
||||||
|
shared_preferences:
|
||||||
|
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||||
|
sqflite:
|
||||||
|
:path: ".symlinks/plugins/sqflite/ios"
|
||||||
|
url_launcher:
|
||||||
|
:path: ".symlinks/plugins/url_launcher/ios"
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
|
||||||
|
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||||
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
|
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||||
|
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
||||||
|
sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0
|
||||||
|
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||||
|
|
||||||
|
COCOAPODS: 1.9.3
|
|
@ -3,7 +3,7 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 46;
|
objectVersion = 50;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
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 */; };
|
||||||
|
F627D0FEEE0CC42B20D97D4D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E5591CE3BD9F89AE791097F /* Pods_Runner.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
@ -31,7 +32,11 @@
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
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>"; };
|
||||||
|
20AF123CE6B282DF5FCC0E08 /* 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>"; };
|
||||||
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>"; };
|
||||||
|
4E5591CE3BD9F89AE791097F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
5D359FC3B8BF643CBF087D7C /* 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>"; };
|
||||||
|
5DC9EF56CF79F18EC6F8E97B /* 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>"; };
|
||||||
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>"; };
|
||||||
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>"; };
|
||||||
|
@ -49,12 +54,31 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
F627D0FEEE0CC42B20D97D4D /* Pods_Runner.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
721C96BBF01C118C12E658F5 /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
20AF123CE6B282DF5FCC0E08 /* Pods-Runner.debug.xcconfig */,
|
||||||
|
5D359FC3B8BF643CBF087D7C /* Pods-Runner.release.xcconfig */,
|
||||||
|
5DC9EF56CF79F18EC6F8E97B /* Pods-Runner.profile.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
78D8D0D60D5196915B006F06 /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4E5591CE3BD9F89AE791097F /* Pods_Runner.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -72,6 +96,8 @@
|
||||||
9740EEB11CF90186004384FC /* Flutter */,
|
9740EEB11CF90186004384FC /* Flutter */,
|
||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
97C146EF1CF9000F007C117D /* Products */,
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
|
721C96BBF01C118C12E658F5 /* Pods */,
|
||||||
|
78D8D0D60D5196915B006F06 /* Frameworks */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
@ -113,12 +139,14 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
2C32CA1979B0B9EA89AB49DE /* [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 */,
|
||||||
|
ADBCA6764A9EF0DC6AA5E56E /* [CP] Embed Pods Frameworks */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
@ -177,6 +205,28 @@
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
2C32CA1979B0B9EA89AB49DE /* [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;
|
||||||
|
};
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -205,6 +255,23 @@
|
||||||
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";
|
||||||
};
|
};
|
||||||
|
ADBCA6764A9EF0DC6AA5E56E /* [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;
|
||||||
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
@ -241,7 +308,6 @@
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
@ -297,13 +363,17 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = NMDSW6KGG7;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
|
@ -318,7 +388,6 @@
|
||||||
};
|
};
|
||||||
97C147031CF9000F007C117D /* Debug */ = {
|
97C147031CF9000F007C117D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
@ -374,7 +443,6 @@
|
||||||
};
|
};
|
||||||
97C147041CF9000F007C117D /* Release */ = {
|
97C147041CF9000F007C117D /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
@ -418,7 +486,8 @@
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
|
@ -431,13 +500,17 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = NMDSW6KGG7;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
|
@ -458,13 +531,17 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = NMDSW6KGG7;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
LIBRARY_SEARCH_PATHS = (
|
LIBRARY_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
<Testables>
|
|
||||||
</Testables>
|
|
||||||
<MacroExpansion>
|
<MacroExpansion>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
|
@ -38,8 +36,8 @@
|
||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</MacroExpansion>
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
<Testables>
|
||||||
</AdditionalOptions>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
|
@ -61,8 +59,6 @@
|
||||||
ReferencedContainer = "container:Runner.xcodeproj">
|
ReferencedContainer = "container:Runner.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
<AdditionalOptions>
|
|
||||||
</AdditionalOptions>
|
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Profile"
|
buildConfiguration = "Profile"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||||
|
|
||||||
|
import 'util/hot_rank.dart';
|
||||||
|
|
||||||
|
enum CommentSortType {
|
||||||
|
hot,
|
||||||
|
top,
|
||||||
|
// ignore: constant_identifier_names
|
||||||
|
new_,
|
||||||
|
old,
|
||||||
|
chat,
|
||||||
|
}
|
||||||
|
|
||||||
class CommentTree {
|
class CommentTree {
|
||||||
CommentView comment;
|
CommentView comment;
|
||||||
List<CommentTree> children;
|
List<CommentTree> children;
|
||||||
|
@ -30,4 +41,69 @@ class CommentTree {
|
||||||
var result = parents.map(gatherChildren).toList();
|
var result = parents.map(gatherChildren).toList();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sort(CommentSortType sortType) {
|
||||||
|
switch (sortType) {
|
||||||
|
case CommentSortType.chat:
|
||||||
|
// throw Exception('i dont do this kinda stuff kido');
|
||||||
|
return;
|
||||||
|
case CommentSortType.hot:
|
||||||
|
return _sort((b, a) =>
|
||||||
|
a.comment.computedHotRank.compareTo(b.comment.computedHotRank));
|
||||||
|
case CommentSortType.new_:
|
||||||
|
return _sort(
|
||||||
|
(b, a) => a.comment.published.compareTo(b.comment.published));
|
||||||
|
case CommentSortType.old:
|
||||||
|
return _sort(
|
||||||
|
(b, a) => b.comment.published.compareTo(a.comment.published));
|
||||||
|
case CommentSortType.top:
|
||||||
|
return _sort((b, a) => a.comment.score.compareTo(b.comment.score));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _sort(int compare(CommentTree a, CommentTree b)) {
|
||||||
|
children.sort(compare);
|
||||||
|
for (var el in children) {
|
||||||
|
el._sort(compare);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<CommentTree> sortList(
|
||||||
|
CommentSortType sortType, List<CommentTree> comms) {
|
||||||
|
switch (sortType) {
|
||||||
|
case CommentSortType.chat:
|
||||||
|
throw Exception('i dont do this kinda stuff kido');
|
||||||
|
case CommentSortType.hot:
|
||||||
|
comms.sort((b, a) =>
|
||||||
|
a.comment.computedHotRank.compareTo(b.comment.computedHotRank));
|
||||||
|
for (var i = 0; i < comms.length; i++) {
|
||||||
|
comms[i].sort(sortType);
|
||||||
|
}
|
||||||
|
return comms;
|
||||||
|
|
||||||
|
case CommentSortType.new_:
|
||||||
|
comms
|
||||||
|
.sort((b, a) => a.comment.published.compareTo(b.comment.published));
|
||||||
|
for (var i = 0; i < comms.length; i++) {
|
||||||
|
comms[i].sort(sortType);
|
||||||
|
}
|
||||||
|
return comms;
|
||||||
|
|
||||||
|
case CommentSortType.old:
|
||||||
|
comms
|
||||||
|
.sort((b, a) => b.comment.published.compareTo(a.comment.published));
|
||||||
|
for (var i = 0; i < comms.length; i++) {
|
||||||
|
comms[i].sort(sortType);
|
||||||
|
}
|
||||||
|
return comms;
|
||||||
|
|
||||||
|
case CommentSortType.top:
|
||||||
|
comms.sort((b, a) => a.comment.score.compareTo(b.comment.score));
|
||||||
|
for (var i = 0; i < comms.length; i++) {
|
||||||
|
comms[i].sort(sortType);
|
||||||
|
}
|
||||||
|
return comms;
|
||||||
|
}
|
||||||
|
throw Exception('unreachable');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
import 'package:esys_flutter_share/esys_flutter_share.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||||
|
|
||||||
|
import '../widgets/comment_section.dart';
|
||||||
|
import '../widgets/post.dart';
|
||||||
|
|
||||||
|
class FullPostPage extends HookWidget {
|
||||||
|
final Future<FullPost> fullPost;
|
||||||
|
final PostView post;
|
||||||
|
|
||||||
|
FullPostPage({@required int id, @required String instanceUrl})
|
||||||
|
: assert(id != null),
|
||||||
|
assert(instanceUrl != null),
|
||||||
|
fullPost = LemmyApi(instanceUrl).v1.getPost(id: id),
|
||||||
|
post = null;
|
||||||
|
FullPostPage.fromPostView(this.post)
|
||||||
|
: fullPost = LemmyApi(post.communityActorId.split('/')[2])
|
||||||
|
.v1
|
||||||
|
.getPost(id: post.id);
|
||||||
|
|
||||||
|
void sharePost() => Share.text('Share post', post.apId, 'text/plain');
|
||||||
|
|
||||||
|
void savePost() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final fullPostSnap = useFuture(this.fullPost);
|
||||||
|
final fullPost = fullPostSnap.data;
|
||||||
|
|
||||||
|
final savedIcon = () {
|
||||||
|
if (fullPostSnap.hasData) {
|
||||||
|
if (fullPost.post.saved == null || !fullPost.post.saved) {
|
||||||
|
return Icons.bookmark_border;
|
||||||
|
} else {
|
||||||
|
return Icons.bookmark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (post != null) {
|
||||||
|
if (post.saved == null || !post.saved) {
|
||||||
|
return Icons.bookmark_border;
|
||||||
|
} else {
|
||||||
|
return Icons.bookmark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Icons.bookmark_border;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
leading: BackButton(),
|
||||||
|
actions: [
|
||||||
|
IconButton(icon: Icon(Icons.share), onPressed: sharePost),
|
||||||
|
IconButton(icon: Icon(savedIcon), onPressed: savePost),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.more_vert), onPressed: () {}), // TODO: more menu
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: fullPostSnap.hasData || post != null
|
||||||
|
// FUTURE SUCCESS
|
||||||
|
? ListView(
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
children: [
|
||||||
|
if (fullPostSnap.hasData)
|
||||||
|
Post(fullPost.post, fullPost: true)
|
||||||
|
else if (post != null)
|
||||||
|
Post(post, fullPost: true)
|
||||||
|
else
|
||||||
|
CircularProgressIndicator(),
|
||||||
|
if (fullPostSnap.hasData)
|
||||||
|
CommentSection(fullPost.comments,
|
||||||
|
postCreatorId: fullPost.post.creatorId)
|
||||||
|
else
|
||||||
|
Container(
|
||||||
|
child: Center(child: CircularProgressIndicator()),
|
||||||
|
padding: EdgeInsets.only(top: 40),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: fullPostSnap.hasError
|
||||||
|
// FUTURE FAILURE
|
||||||
|
? Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.error, size: 30),
|
||||||
|
Padding(padding: EdgeInsets.all(5)),
|
||||||
|
Text('ERROR: ${fullPostSnap.error.toString()}'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
// FUTURE IN PROGRESS
|
||||||
|
: Container(
|
||||||
|
child: Center(child: CircularProgressIndicator()),
|
||||||
|
color: Theme.of(context).canvasColor),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -102,7 +102,7 @@ class UserProfileTab extends HookWidget {
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.push(MaterialPageRoute(builder: (_) => Settings()));
|
.push(MaterialPageRoute(builder: (_) => SettingsPage()));
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|
|
@ -5,7 +5,7 @@ import 'package:provider/provider.dart';
|
||||||
import '../stores/accounts_store.dart';
|
import '../stores/accounts_store.dart';
|
||||||
import '../stores/config_store.dart';
|
import '../stores/config_store.dart';
|
||||||
|
|
||||||
class Settings extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import 'dart:math' show log, max, pow, ln10;
|
||||||
|
|
||||||
|
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||||
|
|
||||||
|
/// Calculates hot rank
|
||||||
|
/// because API always claims it's `0`
|
||||||
|
/// and web version of lemmy also calculates it when loading comments
|
||||||
|
///
|
||||||
|
/// implementation taken from here:
|
||||||
|
/// https://github.com/LemmyNet/lemmy/blob/main/ui/src/utils.ts#L182-L203
|
||||||
|
double _calculateHotRank(int score, DateTime time) {
|
||||||
|
log10(num x) => log(x) / ln10;
|
||||||
|
|
||||||
|
final elapsed = (time.difference(DateTime.now()).inMilliseconds).abs() / 36e5;
|
||||||
|
|
||||||
|
return (10000 * log10(max(1, 3 + score))) / pow(elapsed + 2, 1.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension CommentHotRank on CommentView {
|
||||||
|
double get computedHotRank => _calculateHotRank(score, published);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
Color textColorBasedOnBackground(Color color) {
|
||||||
|
if (color.computeLuminance() > 0.5) {
|
||||||
|
return Colors.black;
|
||||||
|
} else {
|
||||||
|
return Colors.white;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,10 @@
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||||
|
import 'package:timeago/timeago.dart' as timeago;
|
||||||
|
|
||||||
import '../comment_tree.dart';
|
import '../comment_tree.dart';
|
||||||
|
import '../util/text_color.dart';
|
||||||
import 'markdown_text.dart';
|
import 'markdown_text.dart';
|
||||||
|
|
||||||
class Comment extends StatelessWidget {
|
class Comment extends StatelessWidget {
|
||||||
|
@ -14,41 +17,62 @@ class Comment extends StatelessWidget {
|
||||||
@required this.postCreatorId,
|
@required this.postCreatorId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
void _openMoreMenu() {
|
||||||
|
print('OPEN MORE MENU');
|
||||||
|
}
|
||||||
|
|
||||||
void _goToUser() {
|
void _goToUser() {
|
||||||
print('GO TO USER');
|
print('GO TO USER');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _save(bool save) {
|
||||||
|
print('SAVE COMMENT, $save');
|
||||||
|
}
|
||||||
|
|
||||||
|
void _reply() {
|
||||||
|
print('OPEN REPLY BOX');
|
||||||
|
}
|
||||||
|
|
||||||
|
void _vote(VoteType vote) {
|
||||||
|
print('COMMENT VOTE: ${vote.toString()}');
|
||||||
|
}
|
||||||
|
|
||||||
bool get isOP => commentTree.comment.creatorId == postCreatorId;
|
bool get isOP => commentTree.comment.creatorId == postCreatorId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var comment = commentTree.comment;
|
final comment = commentTree.comment;
|
||||||
|
|
||||||
|
final saved = comment.saved ?? false;
|
||||||
|
|
||||||
// decide which username to use
|
// decide which username to use
|
||||||
var username;
|
final username = () {
|
||||||
if (comment.creatorPreferredUsername != null &&
|
if (comment.creatorPreferredUsername != null &&
|
||||||
comment.creatorPreferredUsername != '') {
|
comment.creatorPreferredUsername != '') {
|
||||||
username = comment.creatorPreferredUsername;
|
return comment.creatorPreferredUsername;
|
||||||
} else {
|
} else {
|
||||||
username = '@${comment.creatorName}';
|
return '@${comment.creatorName}';
|
||||||
}
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
var body;
|
final body = () {
|
||||||
if (comment.deleted) {
|
if (comment.deleted) {
|
||||||
body = Flexible(
|
return Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
'comment deleted by creator',
|
'comment deleted by creator',
|
||||||
style: TextStyle(fontStyle: FontStyle.italic),
|
style: TextStyle(fontStyle: FontStyle.italic),
|
||||||
));
|
));
|
||||||
} else if (comment.removed) {
|
} else if (comment.removed) {
|
||||||
body = Flexible(
|
return Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
'comment deleted by moderator',
|
'comment deleted by moderator',
|
||||||
style: TextStyle(fontStyle: FontStyle.italic),
|
style: TextStyle(fontStyle: FontStyle.italic),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
body = Flexible(child: MarkdownText(commentTree.comment.content));
|
return Flexible(child: MarkdownText(commentTree.comment.content));
|
||||||
}
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
|
@ -56,10 +80,10 @@ class Comment extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Row(children: [
|
Row(children: [
|
||||||
if (comment.creatorAvatar != null)
|
if (comment.creatorAvatar != null)
|
||||||
InkWell(
|
Padding(
|
||||||
onTap: _goToUser,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: _goToUser,
|
||||||
child: CachedNetworkImage(
|
child: CachedNetworkImage(
|
||||||
imageUrl: comment.creatorAvatar,
|
imageUrl: comment.creatorAvatar,
|
||||||
height: 20,
|
height: 20,
|
||||||
|
@ -83,17 +107,43 @@ class Comment extends StatelessWidget {
|
||||||
)),
|
)),
|
||||||
onLongPress: _goToUser,
|
onLongPress: _goToUser,
|
||||||
),
|
),
|
||||||
if (isOP) CommentTag('OP', Theme.of(context).accentColor),
|
if (isOP) _CommentTag('OP', Theme.of(context).accentColor),
|
||||||
if (comment.banned) CommentTag('BANNED', Colors.red),
|
if (comment.banned) _CommentTag('BANNED', Colors.red),
|
||||||
if (comment.bannedFromCommunity)
|
if (comment.bannedFromCommunity)
|
||||||
CommentTag('BANNED FROM COMMUNITY', Colors.red),
|
_CommentTag('BANNED FROM COMMUNITY', Colors.red),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
Text(comment.score.toString()),
|
Text(comment.score.toString()),
|
||||||
|
Text(' · '),
|
||||||
|
Text(timeago.format(comment.published, locale: 'en_short')),
|
||||||
]),
|
]),
|
||||||
Row(children: [body]),
|
Row(children: [body]),
|
||||||
Row(children: [
|
Row(children: [
|
||||||
Spacer(),
|
Spacer(),
|
||||||
// actions go here
|
_CommentAction(
|
||||||
|
icon: Icons.more_horiz,
|
||||||
|
onPressed: _openMoreMenu,
|
||||||
|
tooltip: 'more',
|
||||||
|
),
|
||||||
|
_CommentAction(
|
||||||
|
icon: saved ? Icons.bookmark : Icons.bookmark_border,
|
||||||
|
onPressed: () => _save(!saved),
|
||||||
|
tooltip: '${saved ? 'unsave' : 'save'} comment',
|
||||||
|
),
|
||||||
|
_CommentAction(
|
||||||
|
icon: Icons.reply,
|
||||||
|
onPressed: _reply,
|
||||||
|
tooltip: 'reply',
|
||||||
|
),
|
||||||
|
_CommentAction(
|
||||||
|
icon: Icons.arrow_upward,
|
||||||
|
onPressed: () => _vote(VoteType.up),
|
||||||
|
tooltip: 'upvote',
|
||||||
|
),
|
||||||
|
_CommentAction(
|
||||||
|
icon: Icons.arrow_downward,
|
||||||
|
onPressed: () => _vote(VoteType.down),
|
||||||
|
tooltip: 'downvote',
|
||||||
|
),
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -117,11 +167,11 @@ class Comment extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CommentTag extends StatelessWidget {
|
class _CommentTag extends StatelessWidget {
|
||||||
final String text;
|
final String text;
|
||||||
final Color bgColor;
|
final Color bgColor;
|
||||||
|
|
||||||
const CommentTag(this.text, this.bgColor);
|
const _CommentTag(this.text, this.bgColor);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Padding(
|
Widget build(BuildContext context) => Padding(
|
||||||
|
@ -134,10 +184,37 @@ class CommentTag extends StatelessWidget {
|
||||||
padding: EdgeInsets.symmetric(horizontal: 3, vertical: 2),
|
padding: EdgeInsets.symmetric(horizontal: 3, vertical: 2),
|
||||||
child: Text(text,
|
child: Text(text,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: textColorBasedOnBackground(bgColor),
|
||||||
fontSize: Theme.of(context).textTheme.bodyText1.fontSize - 5,
|
fontSize: Theme.of(context).textTheme.bodyText1.fontSize - 5,
|
||||||
fontWeight: FontWeight.w800,
|
fontWeight: FontWeight.w800,
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _CommentAction extends StatelessWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final void Function() onPressed;
|
||||||
|
final String tooltip;
|
||||||
|
|
||||||
|
const _CommentAction({
|
||||||
|
Key key,
|
||||||
|
@required this.icon,
|
||||||
|
@required this.onPressed,
|
||||||
|
@required this.tooltip,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => IconButton(
|
||||||
|
constraints: BoxConstraints.tight(Size(32, 26)),
|
||||||
|
icon: Icon(
|
||||||
|
icon,
|
||||||
|
color: Theme.of(context).iconTheme.color.withAlpha(190),
|
||||||
|
),
|
||||||
|
splashRadius: 25,
|
||||||
|
onPressed: onPressed,
|
||||||
|
iconSize: 22,
|
||||||
|
tooltip: tooltip,
|
||||||
|
padding: EdgeInsets.all(0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -10,13 +10,67 @@ class CommentSection extends HookWidget {
|
||||||
final List<CommentView> rawComments;
|
final List<CommentView> rawComments;
|
||||||
final List<CommentTree> comments;
|
final List<CommentTree> comments;
|
||||||
final int postCreatorId;
|
final int postCreatorId;
|
||||||
|
final CommentSortType sortType;
|
||||||
|
|
||||||
CommentSection(this.rawComments, {@required this.postCreatorId})
|
CommentSection(
|
||||||
: comments = CommentTree.fromList(rawComments),
|
List<CommentView> rawComments, {
|
||||||
|
@required this.postCreatorId,
|
||||||
|
this.sortType = CommentSortType.hot,
|
||||||
|
}) : comments =
|
||||||
|
CommentTree.sortList(sortType, CommentTree.fromList(rawComments)),
|
||||||
|
rawComments = rawComments
|
||||||
|
..sort((b, a) => a.published.compareTo(b.published)),
|
||||||
assert(postCreatorId != null);
|
assert(postCreatorId != null);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Column(children: [
|
Widget build(BuildContext context) {
|
||||||
|
var sorting = useState(sortType);
|
||||||
|
var rawComms = useState(rawComments);
|
||||||
|
var comms = useState(comments);
|
||||||
|
|
||||||
|
void sortComments(CommentSortType sort) {
|
||||||
|
if (sort != sorting.value && sort != CommentSortType.chat) {
|
||||||
|
CommentTree.sortList(sort, comms.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sorting.value = sort;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: Colors.black45),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||||
|
),
|
||||||
|
child: DropdownButton(
|
||||||
|
// TODO: change it to universal BottomModal
|
||||||
|
underline: Container(),
|
||||||
|
isDense: true,
|
||||||
|
onChanged: sortComments,
|
||||||
|
value: sorting.value,
|
||||||
|
items: [
|
||||||
|
DropdownMenuItem(
|
||||||
|
child: Text('Hot'), value: CommentSortType.hot),
|
||||||
|
DropdownMenuItem(
|
||||||
|
child: Text('Top'), value: CommentSortType.top),
|
||||||
|
DropdownMenuItem(
|
||||||
|
child: Text('New'), value: CommentSortType.new_),
|
||||||
|
DropdownMenuItem(
|
||||||
|
child: Text('Old'), value: CommentSortType.old),
|
||||||
|
DropdownMenuItem(
|
||||||
|
child: Text('Chat'), value: CommentSortType.chat),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Spacer(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
// sorting menu goes here
|
// sorting menu goes here
|
||||||
if (comments.isEmpty)
|
if (comments.isEmpty)
|
||||||
Padding(
|
Padding(
|
||||||
|
@ -25,7 +79,15 @@ class CommentSection extends HookWidget {
|
||||||
'no comments yet',
|
'no comments yet',
|
||||||
style: TextStyle(fontStyle: FontStyle.italic),
|
style: TextStyle(fontStyle: FontStyle.italic),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
for (var com in comments) Comment(com, postCreatorId: postCreatorId),
|
else if (sorting.value == CommentSortType.chat)
|
||||||
|
for (final com in rawComms.value)
|
||||||
|
Comment(
|
||||||
|
CommentTree(com),
|
||||||
|
postCreatorId: postCreatorId,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
for (var com in comms.value) Comment(com, postCreatorId: postCreatorId),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import 'package:intl/intl.dart';
|
||||||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||||
import 'package:timeago/timeago.dart' as timeago;
|
import 'package:timeago/timeago.dart' as timeago;
|
||||||
|
|
||||||
|
import '../pages/full_post.dart';
|
||||||
|
import '../url_launcher.dart';
|
||||||
import 'markdown_text.dart';
|
import 'markdown_text.dart';
|
||||||
|
|
||||||
enum MediaType {
|
enum MediaType {
|
||||||
|
@ -28,11 +30,12 @@ MediaType whatType(String url) {
|
||||||
class Post extends StatelessWidget {
|
class Post extends StatelessWidget {
|
||||||
final PostView post;
|
final PostView post;
|
||||||
final String instanceUrl;
|
final String instanceUrl;
|
||||||
|
final bool fullPost;
|
||||||
|
|
||||||
/// nullable
|
/// nullable
|
||||||
final String postUrlDomain;
|
final String postUrlDomain;
|
||||||
|
|
||||||
Post(this.post)
|
Post(this.post, {this.fullPost = false})
|
||||||
: instanceUrl = post.communityActorId.split('/')[2],
|
: instanceUrl = post.communityActorId.split('/')[2],
|
||||||
postUrlDomain = post.url != null ? post.url.split('/')[2] : null;
|
postUrlDomain = post.url != null ? post.url.split('/')[2] : null;
|
||||||
|
|
||||||
|
@ -40,6 +43,7 @@ class Post extends StatelessWidget {
|
||||||
|
|
||||||
void _openLink() {
|
void _openLink() {
|
||||||
print('OPEN LINK');
|
print('OPEN LINK');
|
||||||
|
urlLauncher(post.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _goToUser() {
|
void _goToUser() {
|
||||||
|
@ -47,7 +51,8 @@ class Post extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _goToPost(BuildContext context) {
|
void _goToPost(BuildContext context) {
|
||||||
print('GO TO POST');
|
Navigator.of(context).push(MaterialPageRoute(
|
||||||
|
builder: (context) => FullPostPage.fromPostView(post)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _goToCommunity() {
|
void _goToCommunity() {
|
||||||
|
@ -173,9 +178,17 @@ class Post extends StatelessWidget {
|
||||||
TextSpan(
|
TextSpan(
|
||||||
text:
|
text:
|
||||||
''' · ${timeago.format(post.published, locale: 'en_short')}'''),
|
''' · ${timeago.format(post.published, locale: 'en_short')}'''),
|
||||||
|
if (post.locked) TextSpan(text: ' · 🔒'),
|
||||||
|
if (post.stickied) TextSpan(text: ' · 📌'),
|
||||||
|
if (post.nsfw) TextSpan(text: ' · '),
|
||||||
|
if (post.nsfw)
|
||||||
|
TextSpan(
|
||||||
|
text: 'NSFW',
|
||||||
|
style: TextStyle(color: Colors.red)),
|
||||||
if (postUrlDomain != null)
|
if (postUrlDomain != null)
|
||||||
TextSpan(text: ' · $postUrlDomain'),
|
TextSpan(text: ' · $postUrlDomain'),
|
||||||
if (post.locked) TextSpan(text: ' · 🔒'),
|
if (post.removed) TextSpan(text: ' · REMOVED'),
|
||||||
|
if (post.deleted) TextSpan(text: ' · DELETED'),
|
||||||
],
|
],
|
||||||
))
|
))
|
||||||
]),
|
]),
|
||||||
|
@ -183,6 +196,7 @@ class Post extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
),
|
),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
|
if (!fullPost)
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
|
@ -257,7 +271,9 @@ class Post extends StatelessWidget {
|
||||||
onTap: _openLink,
|
onTap: _openLink,
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(width: 1),
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: Theme.of(context).iconTheme.color.withAlpha(170)),
|
||||||
borderRadius: BorderRadius.circular(5)),
|
borderRadius: BorderRadius.circular(5)),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
|
@ -314,10 +330,12 @@ class Post extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
|
if (!fullPost)
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.share),
|
icon: Icon(Icons.share),
|
||||||
onPressed: () => Share.text('Share post url', post.apId,
|
onPressed: () => Share.text('Share post url', post.apId,
|
||||||
'text/plain')), // TODO: find a way to mark it as url
|
'text/plain')), // TODO: find a way to mark it as url
|
||||||
|
if (!fullPost)
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: post.saved == true
|
icon: post.saved == true
|
||||||
? Icon(Icons.bookmark)
|
? Icon(Icons.bookmark)
|
||||||
|
@ -339,7 +357,7 @@ class Post extends StatelessWidget {
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||||
),
|
),
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () => _goToPost(context),
|
onTap: fullPost ? null : () => _goToPost(context),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
info(),
|
info(),
|
||||||
|
|
Loading…
Reference in New Issue