├── .gitignore ├── .metadata ├── LICENSE ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── flutter_wordpress │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── bloc │ ├── CategoryBloc.dart │ ├── PostBloc.dart │ └── bloc.dart ├── config.dart ├── main.dart ├── models │ ├── Author.dart │ ├── Post.dart │ ├── Tag.dart │ ├── Term.dart │ ├── models.dart │ └── postlisttype.dart ├── screens │ ├── archive.dart │ ├── author.dart │ ├── error.dart │ ├── home.dart │ ├── page.dart │ ├── post.dart │ ├── result.dart │ └── search.dart └── widgets │ ├── CategoryDrawer.dart │ ├── LazyLoadPosts.dart │ ├── PaginatePosts.dart │ ├── PostCard.dart │ ├── PostGrid.dart │ ├── PostList.dart │ └── RelatedPost.dart ├── linux ├── .gitignore ├── Makefile ├── app_configuration.mk ├── flutter │ ├── .template_version │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.mk ├── main.cc ├── window_configuration.cc └── window_configuration.h ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Podfile ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── app_icon_1024.png │ │ ├── app_icon_128.png │ │ ├── app_icon_16.png │ │ ├── app_icon_256.png │ │ ├── app_icon_32.png │ │ ├── app_icon_512.png │ │ └── app_icon_64.png │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configs │ ├── AppInfo.xcconfig │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements ├── pubspec.lock ├── pubspec.yaml ├── screenshots ├── s1.png ├── s2.png ├── s3.png ├── s4.png ├── s5.png ├── s6.png ├── s7.png ├── s8.png └── s9.png ├── test └── widget_test.dart ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ └── Icon-512.png ├── index.html └── manifest.json └── windows ├── .gitignore ├── AppConfiguration.props ├── FlutterBuild.vcxproj ├── Runner.sln ├── Runner.vcxproj ├── Runner.vcxproj.filters ├── flutter ├── .template_version ├── GeneratedPlugins.props ├── generated_plugin_registrant.cc └── generated_plugin_registrant.h ├── runner ├── Runner.rc ├── flutter_window.cpp ├── flutter_window.h ├── main.cpp ├── resource.h ├── resources │ └── app_icon.ico ├── run_loop.cpp ├── run_loop.h ├── runner.exe.manifest ├── win32_window.cpp ├── win32_window.h ├── window_configuration.cpp └── window_configuration.h └── scripts ├── bundle_assets_and_deps.bat └── prepare_dependencies.bat /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 8e5b575174bc4c0c92c1e6978a4b82baced05c23 8 | channel: unknown 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2020, kechankrisna 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_wordpress 2 | 3 | This package is created by simplified get data from wordpress site api version 2, and convert it into the native mobile application. You can clone and edit the app in config.dart file. You can also custom any version as you supposed to do. Any issue or suggestions, please let me know. 4 | 5 | ## Getting Started 6 | 7 | ``` 8 | git clone https://github.com/kechankrisna/flutter_wordpress.git 9 | cd flutter_wordpress && flutter run 10 | ``` 11 | 12 | ## Screenshot 13 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s1.png?raw=true) 14 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s2.png?raw=true) 15 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s3.png?raw=true) 16 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s4.png?raw=true) 17 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s5.png?raw=true) 18 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s6.png?raw=true) 19 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s7.png?raw=true) 20 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s8.png?raw=true) 21 | ![screenshot](https://github.com/kechankrisna/flutter_wordpress/blob/master/screenshots/s9.png?raw=true) 22 | 23 | 24 | This project is a starting point for a Flutter application. 25 | 26 | A few resources to get you started if this is your first Flutter project: 27 | 28 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 29 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 30 | 31 | For help getting started with Flutter, view our 32 | [online documentation](https://flutter.dev/docs), which offers tutorials, 33 | samples, guidance on mobile development, and a full API reference. 34 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.flutter_wordpress" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/flutter_wordpress/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.flutter_wordpress 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | include ':app' 6 | 7 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 8 | def properties = new Properties() 9 | 10 | assert localPropertiesFile.exists() 11 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 12 | 13 | def flutterSdkPath = properties.getProperty("flutter.sdk") 14 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 15 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 16 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | post_install do |installer| 82 | installer.pods_project.targets.each do |target| 83 | target.build_configurations.each do |config| 84 | config.build_settings['ENABLE_BITCODE'] = 'NO' 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - FMDB (2.7.5): 4 | - FMDB/standard (= 2.7.5) 5 | - FMDB/standard (2.7.5) 6 | - path_provider (0.0.1): 7 | - Flutter 8 | - path_provider_macos (0.0.1): 9 | - Flutter 10 | - sqflite (0.0.1): 11 | - Flutter 12 | - FMDB (~> 2.7.2) 13 | - url_launcher (0.0.1): 14 | - Flutter 15 | - url_launcher_macos (0.0.1): 16 | - Flutter 17 | - url_launcher_web (0.0.1): 18 | - Flutter 19 | 20 | DEPENDENCIES: 21 | - Flutter (from `Flutter`) 22 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 23 | - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) 24 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 25 | - url_launcher (from `.symlinks/plugins/url_launcher/ios`) 26 | - url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`) 27 | - url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`) 28 | 29 | SPEC REPOS: 30 | trunk: 31 | - FMDB 32 | 33 | EXTERNAL SOURCES: 34 | Flutter: 35 | :path: Flutter 36 | path_provider: 37 | :path: ".symlinks/plugins/path_provider/ios" 38 | path_provider_macos: 39 | :path: ".symlinks/plugins/path_provider_macos/ios" 40 | sqflite: 41 | :path: ".symlinks/plugins/sqflite/ios" 42 | url_launcher: 43 | :path: ".symlinks/plugins/url_launcher/ios" 44 | url_launcher_macos: 45 | :path: ".symlinks/plugins/url_launcher_macos/ios" 46 | url_launcher_web: 47 | :path: ".symlinks/plugins/url_launcher_web/ios" 48 | 49 | SPEC CHECKSUMS: 50 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec 51 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 52 | path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c 53 | path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 54 | sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0 55 | url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef 56 | url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313 57 | url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c 58 | 59 | PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a 60 | 61 | COCOAPODS: 1.8.4 62 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_wordpress 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/bloc/CategoryBloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:dio/dio.dart'; 3 | import './../config.dart'; 4 | import './../models/models.dart'; 5 | 6 | class CategoryBloc { 7 | List _lists = List(); 8 | List get lists => this._lists; 9 | StreamController> _controller = 10 | StreamController>(); 11 | Stream> get stream => this._controller.stream; 12 | StreamSink> get _streamSink => this._controller.sink; 13 | 14 | CategoryBloc(); 15 | 16 | Future init() async { 17 | return await load(); 18 | } 19 | 20 | Future load({int page: 1}) async { 21 | try { 22 | Response response = await Dio().get("$api/categories?_embed"); 23 | 24 | List datas = response.data; 25 | List _posts = 26 | datas.cast().map((json) => Term.fromJson(json)).toList(); 27 | 28 | _lists.addAll(_posts); 29 | _streamSink.add(_lists); 30 | return true; 31 | } catch (e) { 32 | print("load() method got error $e"); 33 | return false; 34 | } 35 | } 36 | 37 | dispose() { 38 | _controller.close(); 39 | _streamSink.close(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/bloc/PostBloc.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'package:dio/dio.dart'; 3 | import 'package:flutter_wordpress/models/Author.dart'; 4 | import './../config.dart'; 5 | import './../models/models.dart'; 6 | 7 | class PostBloc { 8 | List _lists = List(); 9 | bool loading = false; 10 | List get lists => this._lists; 11 | StreamController> _controller = StreamController>(); 12 | Stream> get stream => this._controller.stream; 13 | StreamSink> get _streamSink => this._controller.sink; 14 | 15 | int perPage; 16 | int currentPage = 1; 17 | int totalPages = 1; 18 | int totalPosts = 0; 19 | String order; 20 | String orderBy; 21 | 22 | Term category; 23 | Author author; 24 | String search; 25 | List excludes; 26 | 27 | PostBloc({ 28 | int perPage: 10, 29 | int currentPage: 1, 30 | String order: "desc", 31 | String orderBy: "date", 32 | Term category, 33 | String search, 34 | Author author, 35 | List excludes: const [], 36 | }) { 37 | this.perPage = perPage; 38 | this.currentPage = currentPage; 39 | this.order = order; 40 | this.orderBy = orderBy; 41 | this.category = category; 42 | this.search = search; 43 | this.excludes = excludes; 44 | this.author = author; 45 | } 46 | 47 | Future refresh() async { 48 | _lists.clear(); 49 | loading = true; 50 | currentPage = 1; 51 | await load(page: currentPage); 52 | return true; 53 | } 54 | 55 | loadMore() { 56 | if (!loading && totalPosts > lists.length) { 57 | loading = true; 58 | currentPage += 1; 59 | load(page: currentPage); 60 | } 61 | print(totalPosts > lists.length); 62 | } 63 | 64 | Future init() async { 65 | loading = true; 66 | await load(page: 1); 67 | return loading; 68 | } 69 | 70 | Future moveToPage({int page: 1}) async { 71 | _lists.clear(); 72 | loading = true; 73 | currentPage = page; 74 | await load(page: currentPage); 75 | return loading; 76 | } 77 | 78 | Future load({int page: 1}) async { 79 | try { 80 | String url = 81 | "$api/posts?_embed&page=$page&per_page=$perPage&order=$order&orderBy=$orderBy"; 82 | if (category != null) { 83 | switch (category.taxonomy) { 84 | case "category": 85 | url += "&categories=${category.id}"; 86 | break; 87 | case "post_tag": 88 | url += "&tags=${category.id}"; 89 | break; 90 | default: 91 | } 92 | } else if (search != null) { 93 | url += "&search=$search"; 94 | } else if (author != null) { 95 | url += "&author=${author.id}"; 96 | } 97 | if (excludes.length > 0) { 98 | url += "&exclude=${excludes.first}"; 99 | } 100 | print(url); 101 | Response response = await Dio().get(url); 102 | 103 | var _totalPosts = response.headers["x-wp-total"].first; 104 | var _totalPages = response.headers["x-wp-totalpages"].first; 105 | print( 106 | "totalPosts $_totalPosts, totalPages $_totalPages, currentPage $currentPage"); 107 | 108 | totalPages = int.parse(_totalPages); 109 | totalPosts = int.parse(_totalPosts); 110 | 111 | List datas = response.data; 112 | List _posts = 113 | datas.cast().map((json) => Post.fromJson(json)).toList(); 114 | 115 | _lists.addAll(_posts); 116 | _streamSink.add(_lists); 117 | loading = false; 118 | return loading; 119 | } catch (e) { 120 | print("load() method got error $e"); 121 | return false; 122 | } 123 | } 124 | 125 | List generate() { 126 | List _posts = []; 127 | final int startIndex = lists.length; 128 | for (var i = startIndex; i < startIndex + 30; i++) { 129 | final Post post = Post( 130 | id: i, 131 | title: "title $i", 132 | content: "Content $i", 133 | excerpt: "Except $i", 134 | ); 135 | _posts.add(post); 136 | } 137 | return _posts; 138 | } 139 | 140 | dispose() { 141 | _controller.close(); 142 | _streamSink.close(); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /lib/bloc/bloc.dart: -------------------------------------------------------------------------------- 1 | library wp_bloc; 2 | export './PostBloc.dart'; -------------------------------------------------------------------------------- /lib/config.dart: -------------------------------------------------------------------------------- 1 | const String app_uri = "https://www.reamker.com/"; 2 | const String app_name = "REAMKER NEWS"; 3 | const String app_description = "វិទ្យាសាស្ត្រ និង បច្ចេកវិទ្យា, ជីវិត, សង្គម, សិល្បៈ, កម្សាន្ត និង ព័ត៌មានផ្សេង ៗ"; 4 | const String app_icon = "https://www.reamker.com/wp-content/uploads/2018/09/Reamker-News-Logo-4.png"; 5 | const String api = "https://www.reamker.com/wp-json/wp/v2"; 6 | const String app_thumbnail = "https://www.laxhel.com/wp-content/plugins/penci-portfolio//images/no-thumbnail.jpg"; 7 | 8 | /* 9 | * api documents 10 | * https://www.reamker.com/wp-json/wp/v2 11 | * https://www.reamker.com/wp-json/wp/v2/posts => all posts or /(?P[\\d]+) for single 12 | * https://www.reamker.com/wp-json/wp/v2/taxonomies => all taxonomies or /(?P[\\d]+) for single 13 | * https://www.reamker.com/wp-json/wp/v2/categories => all categories or /(?P[\\d]+) for single 14 | */ -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/screens/archive.dart'; 3 | import 'package:flutter_wordpress/screens/author.dart'; 4 | import 'package:flutter_wordpress/screens/error.dart'; 5 | import 'package:flutter_wordpress/screens/post.dart'; 6 | import 'package:flutter_wordpress/screens/result.dart'; 7 | import 'package:flutter_wordpress/screens/search.dart'; 8 | import 'screens/home.dart'; 9 | 10 | void main() { 11 | runApp(App()); 12 | } 13 | 14 | class App extends StatelessWidget { 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | title: 'Flutter Wordpress', 19 | theme: ThemeData( 20 | primarySwatch: Colors.blue, 21 | visualDensity: VisualDensity.adaptivePlatformDensity, 22 | ), 23 | initialRoute: '/', 24 | routes: { 25 | '/': (_) => HomeScreen(), 26 | }, 27 | onGenerateRoute: (RouteSettings settings) { 28 | final args = settings.arguments; 29 | switch (settings.name) { 30 | case "/archive": 31 | return MaterialPageRoute( 32 | builder: (_) => ArchiveScreen( 33 | category: args, 34 | ), 35 | ); 36 | break; 37 | case "/author": 38 | return MaterialPageRoute( 39 | builder: (_) => AuthorScreen( 40 | author: args, 41 | ), 42 | ); 43 | break; 44 | case "/search": 45 | return MaterialPageRoute( 46 | builder: (_) => SearchScreen( 47 | search: args, 48 | ), 49 | ); 50 | break; 51 | case "/result": 52 | return MaterialPageRoute( 53 | builder: (_) => ResultScreen( 54 | search: args, 55 | ), 56 | ); 57 | break; 58 | case "/post": 59 | return MaterialPageRoute( 60 | builder: (_) => PostScreen( 61 | post: args, 62 | ), 63 | ); 64 | break; 65 | default: 66 | return MaterialPageRoute(builder: (_) => ErrorScreen()); 67 | break; 68 | } 69 | }, 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/models/Author.dart: -------------------------------------------------------------------------------- 1 | class Author { 2 | final int id; 3 | final String name; 4 | final String url; 5 | final String description; 6 | final String link; 7 | final String slug; 8 | final Map avatar_urls; 9 | 10 | Author( 11 | {this.id, 12 | this.name, 13 | this.url, 14 | this.description, 15 | this.link, 16 | this.slug, 17 | this.avatar_urls}); 18 | 19 | factory Author.fromJson(Map map) { 20 | return Author( 21 | id: map["id"], 22 | name: map["name"], 23 | url: map["url"], 24 | link: map["link"], 25 | slug: map["slug"], 26 | avatar_urls: Map.castFrom(map["avatar_urls"]), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/models/Post.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_wordpress/config.dart'; 2 | import 'package:flutter_wordpress/models/Author.dart'; 3 | import 'package:flutter_wordpress/models/models.dart'; 4 | 5 | class Post { 6 | final int id; 7 | final String date; 8 | final String date_gmt; 9 | final String guid; 10 | final String modified; 11 | final String modified_gmt; 12 | final String slug; 13 | final String status; 14 | final String type; 15 | final String link; 16 | final String title; 17 | final String excerpt; 18 | final String content; 19 | final int feature_media; 20 | final String thumbnail; 21 | final String image; 22 | final String comment_status; 23 | final String ping_status; 24 | final bool sticky; 25 | final String template; 26 | final String format; 27 | final List categories; 28 | final List terms; 29 | final List tags; 30 | final Author author; 31 | 32 | Post({ 33 | this.id, 34 | this.date, 35 | this.date_gmt, 36 | this.guid, 37 | this.modified, 38 | this.modified_gmt, 39 | this.slug, 40 | this.status, 41 | this.type, 42 | this.link, 43 | this.title, 44 | this.excerpt, 45 | this.content, 46 | this.author, 47 | this.feature_media, 48 | this.thumbnail, 49 | this.image, 50 | this.comment_status, 51 | this.ping_status, 52 | this.sticky, 53 | this.template, 54 | this.format, 55 | this.categories, 56 | this.terms, 57 | this.tags, 58 | }); 59 | 60 | factory Post.fromJson(Map map) { 61 | final RegExp reg = RegExp(r"(&|#\w+;)"); 62 | final more_details = 63 | map["_embedded"]["wp:featuredmedia"]?.first["media_details"]; 64 | 65 | List t = []; 66 | for (var terms in map["_embedded"]["wp:term"] as List) { 67 | t = [...terms.cast().map((json) => Term.fromJson(json)).toList(), ...t]; 68 | } 69 | return Post( 70 | id: map['id'], 71 | date: map['date'], 72 | date_gmt: map['date_gmt'], 73 | guid: map['guid']['rendered'], 74 | modified: map['modified'], 75 | modified_gmt: map['modified_gmt'], 76 | slug: map['slug'], 77 | status: map['status'], 78 | type: map['type'], 79 | link: map['link'], 80 | title: map['title']['rendered'] 81 | .replaceAll(RegExp("

|

"), "") 82 | .replaceAll(reg, ""), 83 | excerpt: map['excerpt']['rendered'] 84 | .replaceAll(RegExp("

|

"), "") 85 | .replaceAll(reg, ""), 86 | content: map['content']['rendered'], 87 | author: Author.fromJson((map["_embedded"]['author'] as List).first), 88 | feature_media: map['feature_media'], 89 | thumbnail: more_details != null 90 | ? more_details["sizes"]["medium"]["source_url"] 91 | : map["_embedded"]["wp:featuredmedia"]?.first['source_url'] ?? 92 | app_thumbnail, 93 | image: map["_embedded"]["wp:featuredmedia"]?.first['source_url'] ?? 94 | app_thumbnail, 95 | comment_status: map['comment_status'], 96 | ping_status: map['ping_status'], 97 | sticky: map['sticky'], 98 | template: map['template'], 99 | format: map['format'], 100 | categories: List.castFrom(map['categories']), 101 | terms: t, 102 | tags: List.castFrom(map['tags']), 103 | ); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /lib/models/Tag.dart: -------------------------------------------------------------------------------- 1 | class Tag { 2 | final int id; 3 | final int count; 4 | final String description; 5 | final String link; 6 | final String name; 7 | final String slug; 8 | final String taxonomy; 9 | final List meta; 10 | 11 | Tag({ 12 | this.id, 13 | this.count, 14 | this.description, 15 | this.link, 16 | this.name, 17 | this.slug, 18 | this.taxonomy: "category", 19 | this.meta: const [], 20 | }); 21 | 22 | factory Tag.fromJson(Map map) { 23 | return Tag( 24 | id: map['id'], 25 | count: map['count'], 26 | description: map['description'], 27 | link: map['link'], 28 | name: map['name'], 29 | slug: map['slug'], 30 | taxonomy: map['taxonomy'], 31 | meta: map['meta'], 32 | ); 33 | } 34 | 35 | Map toMap() { 36 | return { 37 | "id": this.id, 38 | "count": this.count, 39 | "description": this.description, 40 | "link": this.link, 41 | "name": this.name, 42 | "slug": this.slug, 43 | "taxonomy": this.taxonomy, 44 | "meta": this.meta, 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/models/Term.dart: -------------------------------------------------------------------------------- 1 | class Term { 2 | final int id; 3 | final int count; 4 | final String description; 5 | final String link; 6 | final String name; 7 | final String slug; 8 | final String taxonomy; 9 | final int parent; 10 | 11 | Term({ 12 | this.id, 13 | this.count, 14 | this.description, 15 | this.link, 16 | this.name, 17 | this.slug, 18 | this.taxonomy: "category", 19 | this.parent: 0, 20 | }); 21 | 22 | factory Term.fromJson(Map map) { 23 | return Term( 24 | id: map['id'], 25 | count: map['count'], 26 | description: map['description'], 27 | link: map['link'], 28 | name: map['name'], 29 | slug: map['slug'], 30 | taxonomy: map['taxonomy'], 31 | parent: map['parent'], 32 | ); 33 | } 34 | 35 | Map toMap() { 36 | return { 37 | "id": this.id, 38 | "count": this.count, 39 | "description": this.description, 40 | "link": this.link, 41 | "name": this.name, 42 | "slug": this.slug, 43 | "taxonomy": this.taxonomy, 44 | "parent": this.parent, 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/models/models.dart: -------------------------------------------------------------------------------- 1 | library wp_model; 2 | 3 | export './Term.dart'; 4 | export './Post.dart'; 5 | export './Tag.dart'; 6 | -------------------------------------------------------------------------------- /lib/models/postlisttype.dart: -------------------------------------------------------------------------------- 1 | enum PostListType { 2 | asListile, 3 | asListCard, 4 | asListRandom, 5 | } 6 | -------------------------------------------------------------------------------- /lib/screens/archive.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/models/models.dart'; 3 | import 'package:flutter_wordpress/models/postlisttype.dart'; 4 | import 'package:flutter_wordpress/widgets/PaginatePosts.dart'; 5 | 6 | class ArchiveScreen extends StatelessWidget { 7 | final Term category; 8 | 9 | const ArchiveScreen({Key key, this.category}) : super(key: key); 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text("Archive: ${category.name}"), 15 | ), 16 | body: PaginatePosts( 17 | postListType: PostListType.asListRandom, 18 | category: category, 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/screens/author.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/models/Author.dart'; 3 | import 'package:flutter_wordpress/models/postlisttype.dart'; 4 | import 'package:flutter_wordpress/widgets/PaginatePosts.dart'; 5 | 6 | class AuthorScreen extends StatelessWidget { 7 | final Author author; 8 | 9 | const AuthorScreen({Key key, this.author}) : super(key: key); 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text("Author: ${author.name}"), 15 | ), 16 | body: PaginatePosts( 17 | postListType: PostListType.asListRandom, 18 | author: author, 19 | ), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/screens/error.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ErrorScreen extends StatefulWidget { 4 | @override 5 | _ErrorScreenState createState() => _ErrorScreenState(); 6 | } 7 | 8 | class _ErrorScreenState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Scaffold( 12 | appBar: AppBar( 13 | title: Text("ErrorScreen"), 14 | ), 15 | body: Container( 16 | alignment: Alignment.center, 17 | child: SingleChildScrollView( 18 | child: Column( 19 | children: [ 20 | Icon( 21 | Icons.info, 22 | size: 55, 23 | color: Colors.grey, 24 | ), 25 | Container( 26 | child: Text( 27 | "404 Error", 28 | style: TextStyle( 29 | color: Colors.red, 30 | fontWeight: FontWeight.bold, 31 | fontSize: 25, 32 | ), 33 | ), 34 | padding: EdgeInsets.all( 35 | 10, 36 | ), 37 | ), 38 | Container( 39 | padding: EdgeInsets.all( 40 | 5, 41 | ), 42 | child: Text("Page error, not found"), 43 | ), 44 | FlatButton.icon( 45 | onPressed: () { 46 | Navigator.of(context).pushNamed("/"); 47 | }, 48 | icon: Icon(Icons.arrow_back), 49 | label: Text("GO HOME"), 50 | ) 51 | ], 52 | ), 53 | ), 54 | ), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/screens/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/models/postlisttype.dart'; 3 | import 'package:flutter_wordpress/widgets/CategoryDrawer.dart'; 4 | import 'package:flutter_wordpress/widgets/LazyLoadPosts.dart'; 5 | import 'package:flutter_wordpress/widgets/PaginatePosts.dart'; 6 | import './../config.dart'; 7 | 8 | 9 | class HomeScreen extends StatefulWidget { 10 | @override 11 | _HomeScreenState createState() => _HomeScreenState(); 12 | } 13 | 14 | class _HomeScreenState extends State { 15 | List> options = [ 16 | { 17 | "name": "LIST", 18 | "type": PostListType.asListile, 19 | }, 20 | { 21 | "name": "CARD", 22 | "type": PostListType.asListCard, 23 | }, 24 | { 25 | "name": "RANDOM", 26 | "type": PostListType.asListRandom, 27 | } 28 | ]; 29 | PostListType _type = PostListType.asListile; 30 | 31 | String _view = "lazy"; 32 | Widget build(BuildContext context) { 33 | return Scaffold( 34 | appBar: AppBar( 35 | title: Text("$app_name"), 36 | actions: [ 37 | DropdownButton( 38 | value: _type, 39 | items: options 40 | .map( 41 | (option) => DropdownMenuItem( 42 | child: Text(option["name"]), 43 | value: option["type"], 44 | ), 45 | ) 46 | .toList(), 47 | onChanged: (type) => setState(() => _type = type), 48 | ), 49 | IconButton( 50 | icon: Icon(Icons.search), 51 | onPressed: () { 52 | Navigator.of(context).pushNamed("/search"); 53 | }, 54 | ), 55 | ], 56 | ), 57 | drawer: CategoryDrawer(), 58 | body: _view == "lazy" 59 | ? LazyLoadPosts( 60 | postListType: _type, 61 | ) 62 | : PaginatePosts( 63 | postListType: _type, 64 | ), 65 | floatingActionButton: FlatButton.icon( 66 | onPressed: () => 67 | setState(() => _view = _view == "lazy" ? "page" : "lazy"), 68 | icon: Icon(Icons.compare_arrows), 69 | label: Text("SWITCH")), 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/screens/page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class PageScreen extends StatefulWidget { 4 | @override 5 | _PageScreenState createState() => _PageScreenState(); 6 | } 7 | 8 | class _PageScreenState extends State { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Scaffold( 12 | appBar: AppBar( 13 | title: Text("PageScreen"), 14 | ), 15 | ); 16 | } 17 | } -------------------------------------------------------------------------------- /lib/screens/post.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | import 'package:cached_network_image/cached_network_image.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter_html/flutter_html.dart'; 6 | import 'package:flutter_html/image_properties.dart'; 7 | import 'package:flutter_wordpress/models/Author.dart'; 8 | import 'package:flutter_wordpress/models/models.dart'; 9 | import 'package:html/dom.dart' as dom; 10 | import 'package:flutter_wordpress/widgets/RelatedPost.dart'; 11 | import 'package:url_launcher/url_launcher.dart'; 12 | 13 | class PostScreen extends StatelessWidget { 14 | final Post post; 15 | 16 | _launchURL(url) async { 17 | if (await canLaunch(url)) { 18 | await launch(url); 19 | } else { 20 | throw 'Could not launch $url'; 21 | } 22 | } 23 | 24 | const PostScreen({Key key, this.post}) : super(key: key); 25 | @override 26 | Widget build(BuildContext context) { 27 | return Scaffold( 28 | appBar: AppBar( 29 | title: Text("Post"), 30 | ), 31 | body: SingleChildScrollView( 32 | child: Column( 33 | crossAxisAlignment: CrossAxisAlignment.start, 34 | children: [ 35 | SizedBox( 36 | height: 250, 37 | child: CachedNetworkImage( 38 | imageUrl: post.image, 39 | imageBuilder: (context, imageProvider) => Container( 40 | decoration: BoxDecoration( 41 | image: DecorationImage( 42 | image: imageProvider, 43 | fit: BoxFit.cover, 44 | ), 45 | ), 46 | ), 47 | placeholder: (context, url) => Container( 48 | alignment: Alignment.center, 49 | child: CircularProgressIndicator(), 50 | ), 51 | errorWidget: (context, url, error) => Icon(Icons.error), 52 | ), 53 | ), 54 | Container( 55 | padding: EdgeInsets.all(5), 56 | child: Text( 57 | "${post.title}", 58 | style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), 59 | textAlign: TextAlign.left, 60 | ), 61 | ), 62 | Html( 63 | customTextAlign: (_) => TextAlign.left, 64 | defaultTextStyle: TextStyle( 65 | fontSize: 16, 66 | ), 67 | imageProperties: ImageProperties( 68 | fit: BoxFit.fitWidth, 69 | matchTextDirection: true, 70 | height: MediaQuery.of(context).size.width * 0.7, 71 | ), 72 | data: post.content, 73 | //Optional parameters: 74 | padding: EdgeInsets.all(5.0), 75 | linkStyle: const TextStyle( 76 | color: Colors.blueAccent, 77 | decorationColor: Colors.blueAccent, 78 | decoration: TextDecoration.underline, 79 | ), 80 | 81 | onLinkTap: (url) => _launchURL("$url"), 82 | customRender: (node, children) { 83 | print(node); 84 | if (node is dom.Element) { 85 | switch (node.localName) { 86 | case "custom_tag": 87 | return Column(children: children); 88 | } 89 | } 90 | }, 91 | ), 92 | Wrap( 93 | alignment: WrapAlignment.start, 94 | runSpacing: 5, 95 | spacing: 5, 96 | children: [ 97 | Container( 98 | padding: EdgeInsets.all(5), 99 | alignment: Alignment.bottomLeft, 100 | child: Text( 101 | "Terms :", 102 | style: TextStyle( 103 | fontSize: 18, 104 | fontWeight: FontWeight.bold, 105 | color: Colors.purple, 106 | ), 107 | textAlign: TextAlign.left, 108 | ), 109 | ), 110 | ...post.terms 111 | .where((term) => 112 | term.taxonomy == "category" || 113 | term.taxonomy == "post_tag") 114 | .map((Term category) => GestureDetector( 115 | onTap: () { 116 | Navigator.of(context) 117 | .pushNamed("/archive", arguments: category); 118 | }, 119 | child: Chip( 120 | label: Text("${category.name}"), 121 | ), 122 | )) 123 | .toList() 124 | ], 125 | ), 126 | Container( 127 | padding: EdgeInsets.all(10), 128 | child: Text( 129 | "Author ", 130 | style: TextStyle( 131 | fontSize: 18, 132 | fontWeight: FontWeight.bold, 133 | color: Colors.black, 134 | ), 135 | textAlign: TextAlign.left, 136 | ), 137 | ), 138 | AuthorBar( 139 | author: post.author, 140 | ), 141 | Container( 142 | padding: EdgeInsets.all(10), 143 | child: Text( 144 | "RECOMMENDED FOR YOU: ", 145 | style: TextStyle( 146 | fontSize: 18, 147 | fontWeight: FontWeight.bold, 148 | color: Colors.black, 149 | ), 150 | textAlign: TextAlign.left, 151 | ), 152 | ), 153 | Container( 154 | child: RelatedPosts( 155 | category: post.terms 156 | .where((term) => term.taxonomy == "category") 157 | .first, 158 | excludes: [this.post.id], 159 | ), 160 | ) 161 | ], 162 | ), 163 | ), 164 | // bottomNavigationBar: BottomAppBar( 165 | // child: Bar, 166 | // ), 167 | ); 168 | } 169 | } 170 | 171 | class AuthorBar extends StatelessWidget { 172 | final Author author; 173 | 174 | const AuthorBar({Key key, this.author}) : super(key: key); 175 | @override 176 | Widget build(BuildContext context) { 177 | return Container( 178 | padding: EdgeInsets.all(10), 179 | child: Row( 180 | mainAxisAlignment: MainAxisAlignment.start, 181 | crossAxisAlignment: CrossAxisAlignment.start, 182 | children: [ 183 | SizedBox( 184 | height: 48, 185 | width: 48, 186 | child: CircleAvatar( 187 | child: CachedNetworkImage( 188 | imageUrl: author.avatar_urls["48"], 189 | imageBuilder: (context, imageProvider) => Container( 190 | decoration: BoxDecoration( 191 | image: DecorationImage( 192 | image: imageProvider, 193 | fit: BoxFit.cover, 194 | ), 195 | ), 196 | ), 197 | placeholder: (context, url) => Container( 198 | alignment: Alignment.center, 199 | child: CircularProgressIndicator(), 200 | ), 201 | errorWidget: (context, url, error) => Icon(Icons.error), 202 | ), 203 | ), 204 | ), 205 | Expanded( 206 | child: InkWell( 207 | onTap: () { 208 | Navigator.of(context).pushNamed("/author", arguments: author); 209 | }, 210 | child: Container( 211 | padding: EdgeInsets.only(left: 10), 212 | child: Column( 213 | mainAxisSize: MainAxisSize.min, 214 | crossAxisAlignment: CrossAxisAlignment.start, 215 | children: [ 216 | Text( 217 | "Name: ${author.name}", 218 | style: TextStyle( 219 | color: Theme.of(context).primaryColor, 220 | ), 221 | ), 222 | if (author.description != null) 223 | Text("${author.description}"), 224 | ], 225 | ), 226 | ), 227 | ), 228 | ), 229 | ], 230 | ), 231 | ); 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /lib/screens/result.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/models/postlisttype.dart'; 3 | import 'package:flutter_wordpress/widgets/PaginatePosts.dart'; 4 | 5 | class ResultScreen extends StatelessWidget { 6 | final String search; 7 | 8 | const ResultScreen({Key key, this.search}) : super(key: key); 9 | @override 10 | Widget build(BuildContext context) { 11 | return Scaffold( 12 | appBar: AppBar( 13 | title: Text("Result: ${this.search}"), 14 | ), 15 | body: PaginatePosts( 16 | postListType: PostListType.asListRandom, 17 | search: this.search, 18 | ), 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/screens/search.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SearchScreen extends StatefulWidget { 4 | final String search; 5 | 6 | const SearchScreen({Key key, this.search}) : super(key: key); 7 | @override 8 | _SearchScreenState createState() => _SearchScreenState(); 9 | } 10 | 11 | class _SearchScreenState extends State { 12 | TextEditingController _controller; 13 | String _search; 14 | 15 | @override 16 | void initState() { 17 | _search = this.widget.search ?? ""; 18 | _controller = 19 | TextEditingController.fromValue(TextEditingValue(text: _search)); 20 | super.initState(); 21 | } 22 | 23 | @override 24 | void dispose() { 25 | _controller?.dispose(); 26 | super.dispose(); 27 | } 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return Scaffold( 32 | appBar: AppBar( 33 | backgroundColor: Colors.white, 34 | leading: IconButton( 35 | color: Colors.black, 36 | icon: Icon( 37 | Icons.arrow_back, 38 | ), 39 | onPressed: () { 40 | Navigator.of(context).pop(); 41 | }, 42 | ), 43 | title: Container( 44 | decoration: BoxDecoration( 45 | color: Colors.white, 46 | ), 47 | child: TextField( 48 | keyboardType: TextInputType.text, 49 | controller: _controller, 50 | onChanged: (value) { 51 | setState(() { 52 | _search = value; 53 | }); 54 | }, 55 | autofocus: true, 56 | decoration: InputDecoration( 57 | suffixIcon: IconButton( 58 | icon: Icon(Icons.search), 59 | onPressed: _search.length <= 0 60 | ? null 61 | : () { 62 | Navigator.of(context) 63 | .pushNamed("/result", arguments: _search); 64 | }, 65 | ), 66 | ), 67 | ), 68 | ), 69 | ), 70 | body: Container( 71 | color: Colors.grey, 72 | ), 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/widgets/CategoryDrawer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/bloc/CategoryBloc.dart'; 3 | import 'package:flutter_wordpress/models/models.dart'; 4 | 5 | import '../config.dart'; 6 | 7 | class CategoryDrawer extends StatefulWidget { 8 | @override 9 | _CategoryDrawerState createState() => _CategoryDrawerState(); 10 | } 11 | 12 | class _CategoryDrawerState extends State { 13 | CategoryBloc _categoryBloc = CategoryBloc(); 14 | @override 15 | void initState() { 16 | _categoryBloc.init(); 17 | super.initState(); 18 | } 19 | 20 | @override 21 | void dispose() { 22 | _categoryBloc?.dispose(); 23 | super.dispose(); 24 | } 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return Drawer( 29 | child: StreamBuilder( 30 | stream: _categoryBloc.stream, 31 | builder: (_, AsyncSnapshot> snapshots) { 32 | if (snapshots.hasData) { 33 | if (snapshots.data.length <= 0) { 34 | return Container( 35 | alignment: Alignment.center, 36 | child: Text("No Data"), 37 | ); 38 | } 39 | final List datas = snapshots.data; 40 | return ListView( 41 | children: [ 42 | DrawerHeader( 43 | padding: EdgeInsets.all(0), 44 | child: UserAccountsDrawerHeader( 45 | onDetailsPressed: () { 46 | Navigator.of(context).pushNamed("/"); 47 | }, 48 | accountName: Text( 49 | "$app_name", 50 | style: TextStyle( 51 | fontSize: 20, 52 | fontWeight: FontWeight.bold, 53 | ), 54 | ), 55 | accountEmail: Text("$app_description"), 56 | decoration: BoxDecoration( 57 | color: Colors.black87, 58 | image: DecorationImage( 59 | image: NetworkImage(app_icon), 60 | ), 61 | ), 62 | ), 63 | ), 64 | ...datas 65 | .map( 66 | (category) => ListTile( 67 | title: Text("${category.name}"), 68 | onTap: () { 69 | Navigator.of(context) 70 | .pushNamed("/archive", arguments: category); 71 | }, 72 | ), 73 | ) 74 | .toList(), 75 | ListTile( 76 | title: Text("More..."), 77 | ) 78 | ], 79 | ); 80 | } 81 | return Container( 82 | alignment: Alignment.center, 83 | child: CircularProgressIndicator(), 84 | ); 85 | }), 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/widgets/LazyLoadPosts.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/bloc/bloc.dart'; 3 | import 'package:flutter_wordpress/models/Author.dart'; 4 | import 'package:flutter_wordpress/models/models.dart'; 5 | import 'package:flutter_wordpress/models/postlisttype.dart'; 6 | import 'package:flutter_wordpress/widgets/PostCard.dart'; 7 | import 'package:flutter_wordpress/widgets/PostList.dart'; 8 | 9 | class LazyLoadPosts extends StatefulWidget { 10 | final PostListType postListType; 11 | final Term category; 12 | final int randomBy; 13 | final String search; 14 | final Author author; 15 | 16 | const LazyLoadPosts({ 17 | Key key, 18 | this.postListType: PostListType.asListile, 19 | this.randomBy: 5, 20 | this.category, 21 | this.search, 22 | this.author, 23 | }) : super(key: key); 24 | @override 25 | _LazyLoadPostsState createState() => _LazyLoadPostsState(); 26 | } 27 | 28 | class _LazyLoadPostsState extends State { 29 | PostBloc _postBloc; 30 | ScrollController _controller = ScrollController(); 31 | bool _refresh = false; 32 | 33 | @override 34 | void initState() { 35 | _postBloc = PostBloc(perPage: 15); 36 | if (this.widget.category != null) { 37 | _postBloc.category = this.widget.category; 38 | } else if (this.widget.search != null) { 39 | _postBloc.search = this.widget.search; 40 | } else if (this.widget.author != null) { 41 | _postBloc.author = this.widget.author; 42 | } 43 | _postBloc?.init(); 44 | 45 | super.initState(); 46 | _controller.addListener(_scrollListener); 47 | } 48 | 49 | //scroll controller 50 | _scrollListener() { 51 | if (_controller.offset >= _controller.position.maxScrollExtent - 20 && 52 | !_controller.position.outOfRange) { 53 | // print('message = "reach the bottom"'); 54 | _postBloc.loadMore(); 55 | } 56 | if (_controller.offset <= _controller.position.minScrollExtent && 57 | !_controller.position.outOfRange) { 58 | print('message = "reach the top"'); 59 | setState(() => _refresh = true); 60 | _postBloc.refresh().then((value) { 61 | setState(() => _refresh = false); 62 | }); 63 | } 64 | } 65 | 66 | Widget _contentWidget({@required Post post}) { 67 | switch (this.widget.postListType) { 68 | case PostListType.asListile: 69 | return PostList( 70 | post: post, 71 | ); 72 | break; 73 | case PostListType.asListCard: 74 | return PostCard( 75 | post: post, 76 | ); 77 | break; 78 | case PostListType.asListRandom: 79 | return post.id % this.widget.randomBy == 0 80 | ? PostCard( 81 | post: post, 82 | ) 83 | : PostList( 84 | post: post, 85 | ); 86 | break; 87 | default: 88 | return Container(); 89 | } 90 | } 91 | 92 | @override 93 | void dispose() { 94 | _postBloc?.dispose(); 95 | _controller?.dispose(); 96 | super.dispose(); 97 | } 98 | 99 | @override 100 | Widget build(BuildContext context) { 101 | return StreamBuilder( 102 | stream: _postBloc.stream, 103 | builder: (_, AsyncSnapshot> snapshots) { 104 | if (snapshots.hasError) { 105 | return Container( 106 | alignment: Alignment.center, 107 | child: Text("Error: ${snapshots.error}"), 108 | ); 109 | } 110 | if (_refresh) 111 | return Container( 112 | alignment: Alignment.center, 113 | child: CircularProgressIndicator(), 114 | ); 115 | 116 | if (snapshots.hasData) { 117 | if (snapshots.data.length <= 0) { 118 | return Container( 119 | alignment: Alignment.center, 120 | child: Text("No Data"), 121 | ); 122 | } 123 | 124 | final List datas = snapshots.data; 125 | return Container( 126 | child: ListView.builder( 127 | controller: _controller, 128 | itemCount: datas.length + 1, 129 | shrinkWrap: true, 130 | itemBuilder: (_, i) => i == datas.length 131 | ? Container( 132 | alignment: Alignment.bottomCenter, 133 | child: CircularProgressIndicator(), 134 | ) 135 | : _contentWidget(post: datas[i]), 136 | ), 137 | ); 138 | } 139 | 140 | return Container( 141 | alignment: Alignment.topCenter, 142 | child: CircularProgressIndicator(), 143 | ); 144 | }, 145 | ); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /lib/widgets/PaginatePosts.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/bloc/bloc.dart'; 3 | import 'package:flutter_wordpress/models/Author.dart'; 4 | import 'package:flutter_wordpress/models/models.dart'; 5 | import 'package:flutter_wordpress/models/postlisttype.dart'; 6 | 7 | import 'PostCard.dart'; 8 | import 'PostList.dart'; 9 | 10 | class PaginatePosts extends StatefulWidget { 11 | final PostListType postListType; 12 | final Term category; 13 | final int randomBy; 14 | final String search; 15 | final Author author; 16 | 17 | const PaginatePosts({ 18 | Key key, 19 | this.postListType: PostListType.asListile, 20 | this.randomBy: 5, 21 | this.category, 22 | this.search, 23 | this.author, 24 | }) : super(key: key); 25 | @override 26 | _PaginatePostsState createState() => _PaginatePostsState(); 27 | } 28 | 29 | class _PaginatePostsState extends State { 30 | int _currentPage = 1; 31 | int _perPage = 15; 32 | PostBloc _postBloc; 33 | bool _refresh = false; 34 | 35 | @override 36 | void initState() { 37 | _postBloc = PostBloc(perPage: _perPage, currentPage: this._currentPage); 38 | if (this.widget.category != null) { 39 | _postBloc.category = this.widget.category; 40 | } else if (this.widget.search != null) { 41 | _postBloc.search = this.widget.search; 42 | } else if (this.widget.author != null) { 43 | _postBloc.author = this.widget.author; 44 | } 45 | 46 | _postBloc?.init(); 47 | 48 | super.initState(); 49 | } 50 | 51 | List _paginationBars({@required int totalPages}) { 52 | List pages = [_currentPage - 1, _currentPage, _currentPage + 1]; 53 | if (_currentPage == 1) { 54 | pages = [_currentPage, _currentPage + 1, _currentPage + 2]; 55 | } else if (_currentPage == totalPages) { 56 | pages = [_currentPage - 2, _currentPage - 1, _currentPage]; 57 | } 58 | if (_postBloc.totalPages < 3) { 59 | pages = 60 | List.generate(_postBloc.totalPages, (index) => index += 1).toList(); 61 | } 62 | 63 | return pages 64 | .map( 65 | (page) => SizedBox( 66 | width: 60, 67 | child: MaterialButton( 68 | shape: RoundedRectangleBorder( 69 | borderRadius: BorderRadius.circular(18.0), 70 | side: BorderSide(color: Theme.of(context).primaryColor), 71 | ), 72 | color: _currentPage == page 73 | ? Theme.of(context).primaryColor 74 | : Colors.white, 75 | onPressed: () { 76 | setState(() => _currentPage = page); 77 | setState(() => _refresh = true); 78 | _postBloc.moveToPage(page: _currentPage).then((value) { 79 | setState(() => _refresh = false); 80 | }); 81 | }, 82 | child: Text( 83 | "$page", 84 | style: TextStyle( 85 | color: _currentPage != page 86 | ? Theme.of(context).primaryColor 87 | : Colors.white, 88 | ), 89 | ), 90 | )), 91 | ) 92 | .toList(); 93 | } 94 | 95 | Widget _contentWidget({@required Post post}) { 96 | switch (this.widget.postListType) { 97 | case PostListType.asListile: 98 | return PostList( 99 | post: post, 100 | ); 101 | break; 102 | case PostListType.asListCard: 103 | return PostCard( 104 | post: post, 105 | ); 106 | break; 107 | case PostListType.asListRandom: 108 | return post.id % this.widget.randomBy == 0 109 | ? PostCard( 110 | post: post, 111 | ) 112 | : PostList( 113 | post: post, 114 | ); 115 | break; 116 | default: 117 | return Container(); 118 | } 119 | } 120 | 121 | @override 122 | void dispose() { 123 | _postBloc?.dispose(); 124 | super.dispose(); 125 | } 126 | 127 | @override 128 | Widget build(BuildContext context) { 129 | return StreamBuilder( 130 | stream: _postBloc.stream, 131 | builder: (_, AsyncSnapshot> snapshots) { 132 | if (snapshots.hasError) { 133 | return Container( 134 | alignment: Alignment.center, 135 | child: Text("Error: ${snapshots.error}"), 136 | ); 137 | } 138 | 139 | if (snapshots.hasData) { 140 | if (_refresh) 141 | return Container( 142 | alignment: Alignment.center, 143 | child: CircularProgressIndicator(), 144 | ); 145 | if (snapshots.data.length <= 0) { 146 | return Container( 147 | alignment: Alignment.center, 148 | child: Text("No Data"), 149 | ); 150 | } 151 | 152 | final List datas = snapshots.data; 153 | return Container( 154 | child: ListView( 155 | children: [ 156 | ...datas 157 | .map((post) => _contentWidget( 158 | post: post, 159 | )) 160 | .toList(), 161 | Container( 162 | alignment: Alignment.center, 163 | child: Row( 164 | mainAxisAlignment: MainAxisAlignment.center, 165 | mainAxisSize: MainAxisSize.min, 166 | children: [ 167 | IconButton( 168 | icon: Icon(Icons.arrow_back_ios), 169 | onPressed: _currentPage == 1 170 | ? null 171 | : () { 172 | setState(() => _currentPage = 173 | _currentPage > 1 ? _currentPage -= 1 : 1); 174 | 175 | setState(() => _refresh = true); 176 | _postBloc 177 | .moveToPage(page: _currentPage) 178 | .then((value) { 179 | setState(() => _refresh = false); 180 | }); 181 | }), 182 | ..._paginationBars(totalPages: _postBloc.totalPages), 183 | IconButton( 184 | icon: Icon(Icons.arrow_forward_ios), 185 | onPressed: _currentPage == _postBloc.totalPages 186 | ? null 187 | : () { 188 | setState(() => _currentPage = 189 | _currentPage < _postBloc.totalPages 190 | ? _currentPage += 1 191 | : _postBloc.totalPages); 192 | setState(() => _refresh = true); 193 | _postBloc 194 | .moveToPage(page: _currentPage) 195 | .then((value) { 196 | setState(() => _refresh = false); 197 | }); 198 | }), 199 | ], 200 | ), 201 | ) 202 | ], 203 | ), 204 | ); 205 | } 206 | 207 | return Container( 208 | alignment: Alignment.center, 209 | child: CircularProgressIndicator(), 210 | ); 211 | }, 212 | ); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /lib/widgets/PostCard.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:intl/intl.dart'; 4 | import './../models/Post.dart'; 5 | 6 | class PostCard extends StatelessWidget { 7 | final Post post; 8 | 9 | const PostCard({Key key, this.post}) : super(key: key); 10 | @override 11 | Widget build(BuildContext context) { 12 | return GestureDetector( 13 | onTap: () => 14 | Navigator.of(context).pushNamed("/post", arguments: this.post), 15 | child: Card( 16 | child: Container( 17 | padding: EdgeInsets.all(5), 18 | child: Column( 19 | mainAxisSize: MainAxisSize.min, 20 | children: [ 21 | SizedBox( 22 | height: 250, 23 | child: CachedNetworkImage( 24 | imageUrl: post.image, 25 | imageBuilder: (context, imageProvider) => Container( 26 | decoration: BoxDecoration( 27 | image: DecorationImage( 28 | image: imageProvider, 29 | fit: BoxFit.cover, 30 | ), 31 | ), 32 | ), 33 | placeholder: (context, url) => Container( 34 | alignment: Alignment.center, 35 | child: CircularProgressIndicator(), 36 | ), 37 | errorWidget: (context, url, error) => Icon(Icons.error), 38 | ), 39 | ), 40 | Text( 41 | "${post.title}", 42 | style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), 43 | textAlign: TextAlign.left, 44 | overflow: TextOverflow.ellipsis, 45 | maxLines: 2, 46 | softWrap: true, 47 | ), 48 | Text( 49 | "${post.excerpt}", 50 | overflow: TextOverflow.ellipsis, 51 | maxLines: 2, 52 | softWrap: true, 53 | ), 54 | Container( 55 | padding: EdgeInsets.all(5), 56 | child: Row( 57 | children: [ 58 | Icon(Icons.date_range), 59 | Text( 60 | " ${DateFormat.yMMMd().format(DateTime.parse(post.date))}", 61 | textAlign: TextAlign.left, 62 | overflow: TextOverflow.ellipsis, 63 | ), 64 | Spacer(), 65 | Text( 66 | " ${post.author.name}", 67 | textAlign: TextAlign.left, 68 | overflow: TextOverflow.ellipsis, 69 | ), 70 | ], 71 | ), 72 | ), 73 | ], 74 | ), 75 | ), 76 | ), 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/widgets/PostGrid.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import './../models/Post.dart'; 4 | 5 | class PostGrid extends StatelessWidget { 6 | final Post post; 7 | final int perRow; 8 | 9 | const PostGrid({Key key, this.post, this.perRow: 3}) : super(key: key); 10 | @override 11 | Widget build(BuildContext context) { 12 | return GestureDetector( 13 | onTap: () => 14 | Navigator.of(context).pushNamed("/post", arguments: this.post), 15 | child: Card( 16 | child: Container( 17 | width: MediaQuery.of(context).size.width / this.perRow, 18 | padding: EdgeInsets.all(5), 19 | child: Column( 20 | mainAxisSize: MainAxisSize.min, 21 | crossAxisAlignment: CrossAxisAlignment.start, 22 | children: [ 23 | CachedNetworkImage( 24 | imageUrl: post.image, 25 | imageBuilder: (context, imageProvider) => Container( 26 | height: 27 | (MediaQuery.of(context).size.width / this.perRow) - 50, 28 | alignment: Alignment.bottomLeft, 29 | decoration: BoxDecoration( 30 | image: DecorationImage( 31 | image: imageProvider, 32 | fit: BoxFit.cover, 33 | colorFilter: ColorFilter.mode( 34 | Colors.black, BlendMode.colorDodge)), 35 | ), 36 | ), 37 | placeholder: (context, url) => Container( 38 | alignment: Alignment.center, 39 | child: CircularProgressIndicator(), 40 | ), 41 | errorWidget: (context, url, error) => Icon(Icons.error), 42 | ), 43 | Text( 44 | "${post.title}", 45 | style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), 46 | textAlign: TextAlign.left, 47 | overflow: TextOverflow.ellipsis, 48 | softWrap: false, 49 | maxLines: 2, 50 | ), 51 | ], 52 | ), 53 | ), 54 | ), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/widgets/PostList.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:intl/intl.dart'; 4 | import './../models/Post.dart'; 5 | 6 | class PostList extends StatelessWidget { 7 | final Post post; 8 | 9 | const PostList({Key key, this.post}) : super(key: key); 10 | @override 11 | Widget build(BuildContext context) { 12 | return GestureDetector( 13 | onTap: () => 14 | Navigator.of(context).pushNamed("/post", arguments: this.post), 15 | child: Card( 16 | child: Container( 17 | padding: EdgeInsets.all(5), 18 | child: Row( 19 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 20 | crossAxisAlignment: CrossAxisAlignment.start, 21 | children: [ 22 | Expanded( 23 | child: Column( 24 | children: [ 25 | Container( 26 | padding: EdgeInsets.all(5), 27 | child: Text( 28 | "${post.title}", 29 | overflow: TextOverflow.ellipsis, 30 | maxLines: 2, 31 | ), 32 | ), 33 | Container( 34 | padding: EdgeInsets.all(5), 35 | child: Row( 36 | children: [ 37 | Icon(Icons.date_range), 38 | Text( 39 | " ${DateFormat.yMMMd().format(DateTime.parse(post.date))}", 40 | textAlign: TextAlign.left, 41 | overflow: TextOverflow.ellipsis, 42 | ), 43 | Spacer(), 44 | Text( 45 | " ${post.author.name}", 46 | textAlign: TextAlign.left, 47 | overflow: TextOverflow.ellipsis, 48 | ), 49 | ], 50 | ), 51 | ), 52 | ], 53 | ), 54 | ), 55 | SizedBox( 56 | width: 125, 57 | height: 100, 58 | child: CachedNetworkImage( 59 | imageUrl: post.thumbnail, 60 | imageBuilder: (context, imageProvider) => Container( 61 | decoration: BoxDecoration( 62 | image: DecorationImage( 63 | image: imageProvider, 64 | fit: BoxFit.cover, 65 | ), 66 | ), 67 | ), 68 | placeholder: (context, url) => Container( 69 | alignment: Alignment.center, 70 | child: CircularProgressIndicator(), 71 | ), 72 | errorWidget: (context, url, error) => Icon(Icons.error), 73 | ), 74 | ) 75 | ], 76 | ), 77 | ), 78 | ), 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/widgets/RelatedPost.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_wordpress/bloc/bloc.dart'; 3 | import 'package:flutter_wordpress/models/models.dart'; 4 | import 'package:flutter_wordpress/widgets/PostGrid.dart'; 5 | 6 | class RelatedPosts extends StatefulWidget { 7 | final Term category; 8 | final List excludes; 9 | 10 | const RelatedPosts({Key key, this.category, this.excludes : const []}) : super(key: key); 11 | @override 12 | _RelatedPostsState createState() => _RelatedPostsState(); 13 | } 14 | 15 | class _RelatedPostsState extends State { 16 | PostBloc _postBloc; 17 | ScrollController _controller = ScrollController(); 18 | bool _refresh = false; 19 | 20 | @override 21 | void initState() { 22 | _postBloc = PostBloc(perPage: 3); 23 | if (this.widget.category != null) { 24 | _postBloc.category = this.widget.category; 25 | } 26 | if(this.widget.excludes.length>0){ 27 | _postBloc.excludes = this.widget.excludes; 28 | } 29 | _postBloc?.init(); 30 | 31 | super.initState(); 32 | _controller.addListener(_scrollListener); 33 | } 34 | 35 | //scroll controller 36 | _scrollListener() { 37 | if (_controller.offset >= _controller.position.maxScrollExtent - 20 && 38 | !_controller.position.outOfRange) { 39 | // print('message = "reach the bottom"'); 40 | _postBloc.loadMore(); 41 | } 42 | if (_controller.offset <= _controller.position.minScrollExtent && 43 | !_controller.position.outOfRange) { 44 | print('message = "reach the top"'); 45 | setState(() => _refresh = true); 46 | _postBloc.refresh().then((value) { 47 | setState(() => _refresh = false); 48 | }); 49 | } 50 | } 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return StreamBuilder( 55 | stream: _postBloc.stream, 56 | builder: (_, AsyncSnapshot> snapshots) { 57 | if (snapshots.hasError) { 58 | return Container( 59 | alignment: Alignment.center, 60 | child: Text("Error: ${snapshots.error}"), 61 | ); 62 | } 63 | if (_refresh) 64 | return Container( 65 | alignment: Alignment.center, 66 | child: CircularProgressIndicator(), 67 | ); 68 | 69 | if (snapshots.hasData) { 70 | if (snapshots.data.length <= 0) { 71 | return Container( 72 | alignment: Alignment.center, 73 | child: Text("No Data"), 74 | ); 75 | } 76 | 77 | final List datas = snapshots.data; 78 | return Container( 79 | width: MediaQuery.of(context).size.width, 80 | 81 | child: SingleChildScrollView( 82 | controller: _controller, 83 | scrollDirection: Axis.horizontal, 84 | child: Container( 85 | child: Row( 86 | children: datas 87 | .map( 88 | (post) => PostGrid( 89 | perRow: 2, 90 | post: post, 91 | ), 92 | ) 93 | .toList(), 94 | ), 95 | ), 96 | ), 97 | ); 98 | } 99 | 100 | return Container( 101 | alignment: Alignment.center, 102 | child: CircularProgressIndicator(), 103 | ); 104 | }, 105 | ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /linux/Makefile: -------------------------------------------------------------------------------- 1 | include app_configuration.mk 2 | 3 | # Default build type. 4 | BUILD=debug 5 | 6 | FLUTTER_MANAGED_DIR=flutter 7 | FLUTTER_EPHEMERAL_DIR=$(FLUTTER_MANAGED_DIR)/ephemeral 8 | 9 | # Configuration provided via flutter tool. 10 | FLUTTER_CONFIG_FILE=$(FLUTTER_EPHEMERAL_DIR)/generated_config.mk 11 | include $(FLUTTER_CONFIG_FILE) 12 | 13 | # Dependency locations 14 | FLUTTER_APP_DIR=$(CURDIR)/.. 15 | FLUTTER_APP_BUILD_DIR=$(FLUTTER_APP_DIR)/build 16 | 17 | OUT_DIR=$(FLUTTER_APP_BUILD_DIR)/linux 18 | OBJ_DIR=$(OUT_DIR)/obj/$(BUILD) 19 | 20 | # Libraries 21 | FLUTTER_LIB_NAME=flutter_linux_glfw 22 | FLUTTER_LIB=$(FLUTTER_EPHEMERAL_DIR)/lib$(FLUTTER_LIB_NAME).so 23 | 24 | # Tools 25 | FLUTTER_BIN=$(FLUTTER_ROOT)/bin/flutter 26 | LINUX_BUILD=$(FLUTTER_ROOT)/packages/flutter_tools/bin/tool_backend.sh 27 | 28 | # Resources 29 | ICU_DATA_NAME=icudtl.dat 30 | ICU_DATA_SOURCE=$(FLUTTER_EPHEMERAL_DIR)/$(ICU_DATA_NAME) 31 | FLUTTER_ASSETS_NAME=flutter_assets 32 | FLUTTER_ASSETS_SOURCE=$(FLUTTER_APP_BUILD_DIR)/$(FLUTTER_ASSETS_NAME) 33 | 34 | # Bundle structure 35 | BUNDLE_OUT_DIR=$(OUT_DIR)/$(BUILD) 36 | BUNDLE_DATA_DIR=$(BUNDLE_OUT_DIR)/data 37 | BUNDLE_LIB_DIR=$(BUNDLE_OUT_DIR)/lib 38 | 39 | BIN_OUT=$(BUNDLE_OUT_DIR)/$(BINARY_NAME) 40 | ICU_DATA_OUT=$(BUNDLE_DATA_DIR)/$(ICU_DATA_NAME) 41 | FLUTTER_LIB_OUT=$(BUNDLE_LIB_DIR)/$(notdir $(FLUTTER_LIB)) 42 | ALL_LIBS_OUT=$(FLUTTER_LIB_OUT) \ 43 | $(foreach lib,$(EXTRA_BUNDLED_LIBRARIES),$(BUNDLE_LIB_DIR)/$(notdir $(lib))) 44 | 45 | # Add relevant code from the wrapper library, which is intended to be statically 46 | # built into the client. 47 | # Use abspath for the wrapper root, which can contain relative paths; the 48 | # intermediate build files will be based on the source path, which will cause 49 | # issues if they start with one or more '../'s. 50 | WRAPPER_ROOT=$(abspath $(FLUTTER_EPHEMERAL_DIR)/cpp_client_wrapper_glfw) 51 | WRAPPER_SOURCES= \ 52 | $(WRAPPER_ROOT)/flutter_window_controller.cc \ 53 | $(WRAPPER_ROOT)/plugin_registrar.cc \ 54 | $(WRAPPER_ROOT)/engine_method_result.cc 55 | 56 | # Use abspath for extra sources, which may also contain relative paths (see 57 | # note above about WRAPPER_ROOT). 58 | SOURCES=main.cc window_configuration.cc \ 59 | flutter/generated_plugin_registrant.cc \ 60 | $(WRAPPER_SOURCES) $(abspath $(EXTRA_SOURCES)) 61 | 62 | # Headers 63 | WRAPPER_INCLUDE_DIR=$(WRAPPER_ROOT)/include 64 | INCLUDE_DIRS=$(FLUTTER_EPHEMERAL_DIR) $(WRAPPER_INCLUDE_DIR) 65 | 66 | # Build settings 67 | ifneq ($(strip $(SYSTEM_LIBRARIES)),) 68 | EXTRA_CPPFLAGS+=$(patsubst -I%,-isystem%,$(shell pkg-config --cflags $(SYSTEM_LIBRARIES))) 69 | EXTRA_LDFLAGS+=$(shell pkg-config --libs $(SYSTEM_LIBRARIES)) 70 | endif 71 | CXX=clang++ 72 | CPPFLAGS.release=-DNDEBUG 73 | CPPFLAGS.profile=$(CPPFLAGS.release) 74 | CXXFLAGS.release=-O2 75 | CXXFLAGS.profile=$(CXXFLAGS.release) 76 | CXXFLAGS=-std=c++14 -Wall -Werror $(CXXFLAGS.$(BUILD)) $(EXTRA_CXXFLAGS) 77 | CPPFLAGS=$(patsubst %,-I%,$(INCLUDE_DIRS)) \ 78 | $(CPPFLAGS.$(BUILD)) $(EXTRA_CPPFLAGS) 79 | LDFLAGS=-L$(BUNDLE_LIB_DIR) \ 80 | -l$(FLUTTER_LIB_NAME) \ 81 | $(EXTRA_LDFLAGS) \ 82 | -Wl,-rpath=\$$ORIGIN/lib 83 | 84 | # Intermediate files. 85 | OBJ_FILES=$(SOURCES:%.cc=$(OBJ_DIR)/%.o) 86 | DEPENDENCY_FILES=$(OBJ_FILES:%.o=%.d) 87 | 88 | # Targets 89 | 90 | .PHONY: all 91 | all: $(BIN_OUT) bundle 92 | 93 | # Add the plugin targets, and their associated settings. 94 | include $(FLUTTER_MANAGED_DIR)/generated_plugins.mk 95 | EXTRA_BUNDLED_LIBRARIES+=$(PLUGIN_LIBRARIES) 96 | EXTRA_LDFLAGS+=$(PLUGIN_LDFLAGS) 97 | EXTRA_CPPFLAGS+=$(PLUGIN_CPPFLAGS) 98 | 99 | # This is a phony target because the flutter tool cannot describe 100 | # its inputs and outputs yet. 101 | .PHONY: sync 102 | sync: $(FLUTTER_CONFIG_FILE) 103 | $(LINUX_BUILD) linux-x64 $(BUILD) 104 | 105 | .PHONY: bundle 106 | bundle: $(ICU_DATA_OUT) $(ALL_LIBS_OUT) bundleflutterassets 107 | 108 | $(BIN_OUT): $(OBJ_FILES) $(ALL_LIBS_OUT) 109 | mkdir -p $(@D) 110 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OBJ_FILES) $(LDFLAGS) -o $@ 111 | 112 | $(WRAPPER_SOURCES) $(FLUTTER_LIB) $(ICU_DATA_SOURCE) $(FLUTTER_ASSETS_SOURCE) \ 113 | $(PLUGIN_TARGETS): | sync 114 | 115 | # Plugin library bundling pattern. 116 | $(BUNDLE_LIB_DIR)/%: $(OUT_DIR)/% 117 | mkdir -p $(BUNDLE_LIB_DIR) 118 | cp $< $@ 119 | 120 | $(FLUTTER_LIB_OUT): $(FLUTTER_LIB) 121 | mkdir -p $(@D) 122 | cp $< $@ 123 | 124 | $(ICU_DATA_OUT): $(ICU_DATA_SOURCE) 125 | mkdir -p $(@D) 126 | cp $< $@ 127 | 128 | -include $(DEPENDENCY_FILES) 129 | 130 | $(OBJ_DIR)/%.o : %.cc | sync 131 | mkdir -p $(@D) 132 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -MMD -c $< -o $@ 133 | 134 | # Fully re-copy the assets directory on each build to avoid having to keep a 135 | # comprehensive list of all asset files here, which would be fragile to changes 136 | # in other files (e.g., adding a new font to pubspec.yaml). 137 | .PHONY: bundleflutterassets 138 | bundleflutterassets: $(FLUTTER_ASSETS_SOURCE) 139 | mkdir -p $(BUNDLE_DATA_DIR) 140 | rsync -rpu --delete $(FLUTTER_ASSETS_SOURCE) $(BUNDLE_DATA_DIR) 141 | 142 | .PHONY: clean 143 | clean: 144 | rm -rf $(OUT_DIR); \ 145 | cd $(FLUTTER_APP_DIR); \ 146 | $(FLUTTER_BIN) clean 147 | -------------------------------------------------------------------------------- /linux/app_configuration.mk: -------------------------------------------------------------------------------- 1 | # This file contains variables that applications are likely to need to 2 | # change, to isolate them from the main Makefile where the build rules are still 3 | # in flux. This should simplify re-creating the runner while preserving local 4 | # changes. 5 | 6 | # Executable name. 7 | BINARY_NAME=flutter_wordpress 8 | # Any extra source files to build. 9 | EXTRA_SOURCES= 10 | # Paths of any additional libraries to be bundled in the output directory. 11 | EXTRA_BUNDLED_LIBRARIES= 12 | # Extra flags (e.g., for library dependencies). 13 | SYSTEM_LIBRARIES= 14 | EXTRA_CXXFLAGS= 15 | EXTRA_CPPFLAGS= 16 | EXTRA_LDFLAGS= -------------------------------------------------------------------------------- /linux/flutter/.template_version: -------------------------------------------------------------------------------- 1 | 1 -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #include "generated_plugin_registrant.h" 6 | 7 | 8 | void RegisterPlugins(flutter::PluginRegistry* registry) { 9 | } 10 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 6 | #define GENERATED_PLUGIN_REGISTRANT_ 7 | 8 | #include 9 | 10 | // Registers Flutter plugins. 11 | void RegisterPlugins(flutter::PluginRegistry* registry); 12 | 13 | #endif // GENERATED_PLUGIN_REGISTRANT_ 14 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.mk: -------------------------------------------------------------------------------- 1 | # Plugins to include in the build. 2 | GENERATED_PLUGINS=\ 3 | 4 | GENERATED_PLUGINS_DIR=flutter/ephemeral/.plugin_symlinks 5 | # A plugin library name plugin name with _plugin appended. 6 | GENERATED_PLUGIN_LIB_NAMES=$(foreach plugin,$(GENERATED_PLUGINS),$(plugin)_plugin) 7 | 8 | # Variables for use in the enclosing Makefile. Changes to these names are 9 | # breaking changes. 10 | PLUGIN_TARGETS=$(GENERATED_PLUGINS) 11 | PLUGIN_LIBRARIES=$(foreach plugin,$(GENERATED_PLUGIN_LIB_NAMES),\ 12 | $(OUT_DIR)/lib$(plugin).so) 13 | PLUGIN_LDFLAGS=$(patsubst %,-l%,$(GENERATED_PLUGIN_LIB_NAMES)) 14 | PLUGIN_CPPFLAGS=$(foreach plugin,$(GENERATED_PLUGINS),\ 15 | -I$(GENERATED_PLUGINS_DIR)/$(plugin)/linux) 16 | 17 | # Targets 18 | 19 | # Implicit rules don't match phony targets, so list plugin builds explicitly. 20 | 21 | .PHONY: $(GENERATED_PLUGINS) 22 | $(GENERATED_PLUGINS): 23 | make -C $(GENERATED_PLUGINS_DIR)/$@/linux \ 24 | OUT_DIR=$(OUT_DIR) \ 25 | FLUTTER_EPHEMERAL_DIR="$(abspath flutter/ephemeral)" 26 | -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "flutter/generated_plugin_registrant.h" 11 | #include "window_configuration.h" 12 | 13 | namespace { 14 | 15 | // Returns the path of the directory containing this executable, or an empty 16 | // string if the directory cannot be found. 17 | std::string GetExecutableDirectory() { 18 | char buffer[PATH_MAX + 1]; 19 | ssize_t length = readlink("/proc/self/exe", buffer, sizeof(buffer)); 20 | if (length > PATH_MAX) { 21 | std::cerr << "Couldn't locate executable" << std::endl; 22 | return ""; 23 | } 24 | std::string executable_path(buffer, length); 25 | size_t last_separator_position = executable_path.find_last_of('/'); 26 | if (last_separator_position == std::string::npos) { 27 | std::cerr << "Unabled to find parent directory of " << executable_path 28 | << std::endl; 29 | return ""; 30 | } 31 | return executable_path.substr(0, last_separator_position); 32 | } 33 | 34 | } // namespace 35 | 36 | int main(int argc, char **argv) { 37 | // Resources are located relative to the executable. 38 | std::string base_directory = GetExecutableDirectory(); 39 | if (base_directory.empty()) { 40 | base_directory = "."; 41 | } 42 | std::string data_directory = base_directory + "/data"; 43 | std::string assets_path = data_directory + "/flutter_assets"; 44 | std::string icu_data_path = data_directory + "/icudtl.dat"; 45 | 46 | // Arguments for the Flutter Engine. 47 | std::vector arguments; 48 | 49 | flutter::FlutterWindowController flutter_controller(icu_data_path); 50 | flutter::WindowProperties window_properties = {}; 51 | window_properties.title = kFlutterWindowTitle; 52 | window_properties.width = kFlutterWindowWidth; 53 | window_properties.height = kFlutterWindowHeight; 54 | 55 | // Start the engine. 56 | if (!flutter_controller.CreateWindow(window_properties, assets_path, 57 | arguments)) { 58 | return EXIT_FAILURE; 59 | } 60 | RegisterPlugins(&flutter_controller); 61 | 62 | // Run until the window is closed. 63 | while (flutter_controller.RunEventLoopWithTimeout( 64 | std::chrono::milliseconds::max())) { 65 | } 66 | return EXIT_SUCCESS; 67 | } 68 | -------------------------------------------------------------------------------- /linux/window_configuration.cc: -------------------------------------------------------------------------------- 1 | #include "window_configuration.h" 2 | 3 | const char *kFlutterWindowTitle = "flutter_wordpress"; 4 | const unsigned int kFlutterWindowWidth = 800; 5 | const unsigned int kFlutterWindowHeight = 600; 6 | -------------------------------------------------------------------------------- /linux/window_configuration.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_CONFIGURATION_ 2 | #define WINDOW_CONFIGURATION_ 3 | 4 | // This is a temporary approach to isolate common customizations from main.cpp, 5 | // where the APIs are still in flux. This should simplify re-creating the 6 | // runner while preserving local changes. 7 | // 8 | // Longer term there should be simpler configuration options for common 9 | // customizations like this, without requiring native code changes. 10 | 11 | extern const char *kFlutterWindowTitle; 12 | extern const unsigned int kFlutterWindowWidth; 13 | extern const unsigned int kFlutterWindowHeight; 14 | 15 | #endif // WINDOW_CONFIGURATION_ 16 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import path_provider_macos 9 | import sqflite 10 | import url_launcher_macos 11 | 12 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 13 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 14 | SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) 15 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 16 | } 17 | -------------------------------------------------------------------------------- /macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def parse_KV_file(file, separator='=') 13 | file_abs_path = File.expand_path(file) 14 | if !File.exists? file_abs_path 15 | return []; 16 | end 17 | pods_ary = [] 18 | skip_line_start_symbols = ["#", "/"] 19 | File.foreach(file_abs_path) { |line| 20 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 21 | plugin = line.split(pattern=separator) 22 | if plugin.length == 2 23 | podname = plugin[0].strip() 24 | path = plugin[1].strip() 25 | podpath = File.expand_path("#{path}", file_abs_path) 26 | pods_ary.push({:name => podname, :path => podpath}); 27 | else 28 | puts "Invalid plugin specification: #{line}" 29 | end 30 | } 31 | return pods_ary 32 | end 33 | 34 | def pubspec_supports_macos(file) 35 | file_abs_path = File.expand_path(file) 36 | if !File.exists? file_abs_path 37 | return false; 38 | end 39 | File.foreach(file_abs_path) { |line| 40 | return true if line =~ /^\s*macos:/ 41 | } 42 | return false 43 | end 44 | 45 | target 'Runner' do 46 | use_frameworks! 47 | use_modular_headers! 48 | 49 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 50 | # referring to absolute paths on developers' machines. 51 | ephemeral_dir = File.join('Flutter', 'ephemeral') 52 | symlink_dir = File.join(ephemeral_dir, '.symlinks') 53 | symlink_plugins_dir = File.join(symlink_dir, 'plugins') 54 | system("rm -rf #{symlink_dir}") 55 | system("mkdir -p #{symlink_plugins_dir}") 56 | 57 | # Flutter Pods 58 | generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig')) 59 | if generated_xcconfig.empty? 60 | puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 61 | end 62 | generated_xcconfig.map { |p| 63 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 64 | symlink = File.join(symlink_dir, 'flutter') 65 | File.symlink(File.dirname(p[:path]), symlink) 66 | pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path])) 67 | end 68 | } 69 | 70 | # Plugin Pods 71 | plugin_pods = parse_KV_file('../.flutter-plugins') 72 | plugin_pods.map { |p| 73 | symlink = File.join(symlink_plugins_dir, p[:name]) 74 | File.symlink(p[:path], symlink) 75 | if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml')) 76 | pod p[:name], :path => File.join(symlink, 'macos') 77 | end 78 | } 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = flutter_wordpress 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWordpress 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2020 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.4.1" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.0.0" 18 | cached_network_image: 19 | dependency: "direct main" 20 | description: 21 | name: cached_network_image 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.2.0" 25 | charcode: 26 | dependency: transitive 27 | description: 28 | name: charcode 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.1.3" 32 | clock: 33 | dependency: transitive 34 | description: 35 | name: clock 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.0.1" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.14.12" 46 | convert: 47 | dependency: transitive 48 | description: 49 | name: convert 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "2.1.1" 53 | crypto: 54 | dependency: transitive 55 | description: 56 | name: crypto 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "2.1.4" 60 | csslib: 61 | dependency: transitive 62 | description: 63 | name: csslib 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "0.16.1" 67 | cupertino_icons: 68 | dependency: "direct main" 69 | description: 70 | name: cupertino_icons 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "0.1.3" 74 | dio: 75 | dependency: "direct main" 76 | description: 77 | name: dio 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "3.0.9" 81 | fake_async: 82 | dependency: transitive 83 | description: 84 | name: fake_async 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "1.1.0" 88 | file: 89 | dependency: transitive 90 | description: 91 | name: file 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "5.1.0" 95 | flutter: 96 | dependency: "direct main" 97 | description: flutter 98 | source: sdk 99 | version: "0.0.0" 100 | flutter_cache_manager: 101 | dependency: transitive 102 | description: 103 | name: flutter_cache_manager 104 | url: "https://pub.dartlang.org" 105 | source: hosted 106 | version: "1.2.2" 107 | flutter_html: 108 | dependency: "direct main" 109 | description: 110 | name: flutter_html 111 | url: "https://pub.dartlang.org" 112 | source: hosted 113 | version: "0.11.1" 114 | flutter_test: 115 | dependency: "direct dev" 116 | description: flutter 117 | source: sdk 118 | version: "0.0.0" 119 | flutter_web_plugins: 120 | dependency: transitive 121 | description: flutter 122 | source: sdk 123 | version: "0.0.0" 124 | html: 125 | dependency: transitive 126 | description: 127 | name: html 128 | url: "https://pub.dartlang.org" 129 | source: hosted 130 | version: "0.14.0+3" 131 | http: 132 | dependency: transitive 133 | description: 134 | name: http 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "0.12.1" 138 | http_parser: 139 | dependency: transitive 140 | description: 141 | name: http_parser 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "3.1.4" 145 | intl: 146 | dependency: "direct main" 147 | description: 148 | name: intl 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "0.16.1" 152 | js: 153 | dependency: transitive 154 | description: 155 | name: js 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "0.6.1+1" 159 | matcher: 160 | dependency: transitive 161 | description: 162 | name: matcher 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "0.12.6" 166 | meta: 167 | dependency: transitive 168 | description: 169 | name: meta 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "1.1.8" 173 | path: 174 | dependency: transitive 175 | description: 176 | name: path 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "1.7.0" 180 | path_provider: 181 | dependency: transitive 182 | description: 183 | name: path_provider 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "1.6.7" 187 | path_provider_macos: 188 | dependency: transitive 189 | description: 190 | name: path_provider_macos 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "0.0.4+1" 194 | path_provider_platform_interface: 195 | dependency: transitive 196 | description: 197 | name: path_provider_platform_interface 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "1.0.1" 201 | pedantic: 202 | dependency: transitive 203 | description: 204 | name: pedantic 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "1.9.0" 208 | platform: 209 | dependency: transitive 210 | description: 211 | name: platform 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "2.2.1" 215 | plugin_platform_interface: 216 | dependency: transitive 217 | description: 218 | name: plugin_platform_interface 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "1.0.2" 222 | rxdart: 223 | dependency: transitive 224 | description: 225 | name: rxdart 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "0.24.0" 229 | sky_engine: 230 | dependency: transitive 231 | description: flutter 232 | source: sdk 233 | version: "0.0.99" 234 | source_span: 235 | dependency: transitive 236 | description: 237 | name: source_span 238 | url: "https://pub.dartlang.org" 239 | source: hosted 240 | version: "1.7.0" 241 | sqflite: 242 | dependency: transitive 243 | description: 244 | name: sqflite 245 | url: "https://pub.dartlang.org" 246 | source: hosted 247 | version: "1.3.0" 248 | sqflite_common: 249 | dependency: transitive 250 | description: 251 | name: sqflite_common 252 | url: "https://pub.dartlang.org" 253 | source: hosted 254 | version: "1.0.0+1" 255 | stack_trace: 256 | dependency: transitive 257 | description: 258 | name: stack_trace 259 | url: "https://pub.dartlang.org" 260 | source: hosted 261 | version: "1.9.3" 262 | stream_channel: 263 | dependency: transitive 264 | description: 265 | name: stream_channel 266 | url: "https://pub.dartlang.org" 267 | source: hosted 268 | version: "2.0.0" 269 | string_scanner: 270 | dependency: transitive 271 | description: 272 | name: string_scanner 273 | url: "https://pub.dartlang.org" 274 | source: hosted 275 | version: "1.0.5" 276 | synchronized: 277 | dependency: transitive 278 | description: 279 | name: synchronized 280 | url: "https://pub.dartlang.org" 281 | source: hosted 282 | version: "2.2.0" 283 | term_glyph: 284 | dependency: transitive 285 | description: 286 | name: term_glyph 287 | url: "https://pub.dartlang.org" 288 | source: hosted 289 | version: "1.1.0" 290 | test_api: 291 | dependency: transitive 292 | description: 293 | name: test_api 294 | url: "https://pub.dartlang.org" 295 | source: hosted 296 | version: "0.2.15" 297 | typed_data: 298 | dependency: transitive 299 | description: 300 | name: typed_data 301 | url: "https://pub.dartlang.org" 302 | source: hosted 303 | version: "1.1.6" 304 | url_launcher: 305 | dependency: "direct main" 306 | description: 307 | name: url_launcher 308 | url: "https://pub.dartlang.org" 309 | source: hosted 310 | version: "5.4.5" 311 | url_launcher_macos: 312 | dependency: transitive 313 | description: 314 | name: url_launcher_macos 315 | url: "https://pub.dartlang.org" 316 | source: hosted 317 | version: "0.0.1+5" 318 | url_launcher_platform_interface: 319 | dependency: transitive 320 | description: 321 | name: url_launcher_platform_interface 322 | url: "https://pub.dartlang.org" 323 | source: hosted 324 | version: "1.0.6" 325 | url_launcher_web: 326 | dependency: transitive 327 | description: 328 | name: url_launcher_web 329 | url: "https://pub.dartlang.org" 330 | source: hosted 331 | version: "0.1.1+2" 332 | uuid: 333 | dependency: transitive 334 | description: 335 | name: uuid 336 | url: "https://pub.dartlang.org" 337 | source: hosted 338 | version: "2.0.4" 339 | vector_math: 340 | dependency: transitive 341 | description: 342 | name: vector_math 343 | url: "https://pub.dartlang.org" 344 | source: hosted 345 | version: "2.0.8" 346 | sdks: 347 | dart: ">=2.7.0 <3.0.0" 348 | flutter: ">=1.12.13+hotfix.5 <2.0.0" 349 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_wordpress 2 | description: This package is created by simplified get data from wordpress site api version 2, and convert it into the native mobile application. You can clone and edit the app in config.dart file. You can also custom any version as you supposed to do. Any issue or suggestions, please let me know. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | dio: ^3.0.9 27 | cached_network_image: ^2.1.0+1 28 | flutter_html: ^0.11.1 29 | url_launcher: ^5.4.5 30 | intl: ^0.16.1 31 | 32 | 33 | # The following adds the Cupertino Icons font to your application. 34 | # Use with the CupertinoIcons class for iOS style icons. 35 | cupertino_icons: ^0.1.3 36 | 37 | dev_dependencies: 38 | flutter_test: 39 | sdk: flutter 40 | 41 | # For information on the generic Dart part of this file, see the 42 | # following page: https://dart.dev/tools/pub/pubspec 43 | 44 | # The following section is specific to Flutter. 45 | flutter: 46 | 47 | # The following line ensures that the Material Icons font is 48 | # included with your application, so that you can use the icons in 49 | # the material Icons class. 50 | uses-material-design: true 51 | 52 | # To add assets to your application, add an assets section, like this: 53 | # assets: 54 | # - images/a_dot_burr.jpeg 55 | # - images/a_dot_ham.jpeg 56 | 57 | # An image asset can refer to one or more resolution-specific "variants", see 58 | # https://flutter.dev/assets-and-images/#resolution-aware. 59 | 60 | # For details regarding adding assets from package dependencies, see 61 | # https://flutter.dev/assets-and-images/#from-packages 62 | 63 | # To add custom fonts to your application, add a fonts section here, 64 | # in this "flutter" section. Each entry in this list should have a 65 | # "family" key with the font family name, and a "fonts" key with a 66 | # list giving the asset and other descriptors for the font. For 67 | # example: 68 | # fonts: 69 | # - family: Schyler 70 | # fonts: 71 | # - asset: fonts/Schyler-Regular.ttf 72 | # - asset: fonts/Schyler-Italic.ttf 73 | # style: italic 74 | # - family: Trajan Pro 75 | # fonts: 76 | # - asset: fonts/TrajanPro.ttf 77 | # - asset: fonts/TrajanPro_Bold.ttf 78 | # weight: 700 79 | # 80 | # For details regarding fonts from package dependencies, 81 | # see https://flutter.dev/custom-fonts/#from-packages 82 | -------------------------------------------------------------------------------- /screenshots/s1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s1.png -------------------------------------------------------------------------------- /screenshots/s2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s2.png -------------------------------------------------------------------------------- /screenshots/s3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s3.png -------------------------------------------------------------------------------- /screenshots/s4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s4.png -------------------------------------------------------------------------------- /screenshots/s5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s5.png -------------------------------------------------------------------------------- /screenshots/s6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s6.png -------------------------------------------------------------------------------- /screenshots/s7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s7.png -------------------------------------------------------------------------------- /screenshots/s8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s8.png -------------------------------------------------------------------------------- /screenshots/s9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/screenshots/s9.png -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_wordpress/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(App()); 17 | 18 | // // Verify that our counter starts at 0. 19 | // expect(find.text('0'), findsOneWidget); 20 | // expect(find.text('1'), findsNothing); 21 | 22 | // // Tap the '+' icon and trigger a frame. 23 | // await tester.tap(find.byIcon(Icons.add)); 24 | // await tester.pump(); 25 | 26 | // // Verify that our counter has incremented. 27 | // expect(find.text('0'), findsNothing); 28 | // expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | flutter_wordpress 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_wordpress", 3 | "short_name": "flutter_wordpress", 4 | "start_url": ".", 5 | "display": "minimal-ui", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /windows/AppConfiguration.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flutter_wordpress 5 | 6 | 7 | -------------------------------------------------------------------------------- /windows/FlutterBuild.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Profile 10 | x64 11 | 12 | 13 | Release 14 | x64 15 | 16 | 17 | 18 | 15.0 19 | {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} 20 | Flutter Build 21 | 10.0 22 | 23 | 24 | 25 | v141 26 | v142 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | "$(ProjectDir)scripts\prepare_dependencies" $(Configuration) 41 | Running Flutter backend build 42 | force_to_run_every_time 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /windows/Runner.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29709.97 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Runner", "Runner.vcxproj", "{5A827760-CF8B-408A-99A3-B6C0AD2271E7}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} = {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Flutter Build", "FlutterBuild.vcxproj", "{6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}" 12 | EndProject 13 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Flutter Plugins", "Flutter Plugins", "{5C2E738A-1DD3-445A-AAC8-EEB9648DD07C}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|x64 = Debug|x64 18 | Profile|x64 = Profile|x64 19 | Release|x64 = Release|x64 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Debug|x64.ActiveCfg = Debug|x64 23 | {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Debug|x64.Build.0 = Debug|x64 24 | {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Profile|x64.ActiveCfg = Profile|x64 25 | {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Profile|x64.Build.0 = Profile|x64 26 | {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Release|x64.ActiveCfg = Release|x64 27 | {5A827760-CF8B-408A-99A3-B6C0AD2271E7}.Release|x64.Build.0 = Release|x64 28 | {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.ActiveCfg = Debug|x64 29 | {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Debug|x64.Build.0 = Debug|x64 30 | {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Profile|x64.ActiveCfg = Profile|x64 31 | {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Profile|x64.Build.0 = Profile|x64 32 | {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Release|x64.ActiveCfg = Release|x64 33 | {6419BF13-6ECD-4CD2-9E85-E566A1F03F8F}.Release|x64.Build.0 = Release|x64 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {B8A69CB0-A974-4774-9EBD-1E5EECACD186} 40 | EndGlobalSection 41 | GlobalSection(NestedProjects) = preSolution 42 | EndGlobalSection 43 | EndGlobal -------------------------------------------------------------------------------- /windows/Runner.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Profile 10 | x64 11 | 12 | 13 | Release 14 | x64 15 | 16 | 17 | 18 | 15.0 19 | {5A827760-CF8B-408A-99A3-B6C0AD2271E7} 20 | flutter_wordpress 21 | 10.0 22 | 23 | 24 | 25 | Application 26 | true 27 | v141 28 | v142 29 | Unicode 30 | 31 | 32 | Application 33 | false 34 | v141 35 | v142 36 | true 37 | Unicode 38 | 39 | 40 | Application 41 | false 42 | v141 43 | v142 44 | true 45 | Unicode 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | $(ProjectDir)..\build\windows\$(Platform)\$(Configuration)\$(ProjectName)\ 73 | $(ProjectDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\ 74 | 75 | 76 | $(ProjectDir)..\build\windows\$(Platform)\$(Configuration)\$(ProjectName)\ 77 | $(ProjectDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\ 78 | 79 | 80 | $(ProjectDir)..\build\windows\$(Platform)\$(Configuration)\$(ProjectName)\ 81 | $(ProjectDir)..\build\windows\intermediates\$(Platform)\$(Configuration)\$(ProjectName)\ 82 | 83 | 84 | 85 | Level4 86 | Disabled 87 | true 88 | true 89 | $(ProjectDir);$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories) 90 | _MBCS;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions) 91 | true 92 | 4100 93 | 94 | 95 | flutter_windows.dll.lib;%(AdditionalDependencies) 96 | $(FLUTTER_EPHEMERAL_DIR);$(OutDir)..\Plugins;%(AdditionalLibraryDirectories) 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | "$(ProjectDir)scripts\bundle_assets_and_deps" "$(FLUTTER_EPHEMERAL_DIR)\" "$(OutputPath)" "$(OutputPath)..\Plugins\" "$(TargetFileName)" 120 | 121 | 122 | Bundling dependencies 123 | Dummy_Run_Always 124 | 125 | 126 | 127 | 128 | 129 | 130 | Level4 131 | MaxSpeed 132 | true 133 | true 134 | true 135 | true 136 | $(ProjectDir);$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories) 137 | _MBCS;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions) 138 | true 139 | 4100 140 | 141 | 142 | true 143 | true 144 | flutter_windows.dll.lib;%(AdditionalDependencies) 145 | $(FLUTTER_EPHEMERAL_DIR);$(OutDir)..\Plugins;%(AdditionalLibraryDirectories) 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | "$(ProjectDir)scripts\bundle_assets_and_deps" "$(FLUTTER_EPHEMERAL_DIR)\" "$(OutputPath)" "$(OutputPath)..\Plugins\" "$(TargetFileName)" 169 | 170 | 171 | Bundling dependencies 172 | Dummy_Run_Always 173 | 174 | 175 | 176 | 177 | 178 | 179 | Level4 180 | MaxSpeed 181 | true 182 | true 183 | true 184 | true 185 | $(ProjectDir);$(FLUTTER_EPHEMERAL_DIR);$(FLUTTER_EPHEMERAL_DIR)\cpp_client_wrapper\include;%(AdditionalIncludeDirectories) 186 | _MBCS;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions) 187 | true 188 | 4100 189 | 190 | 191 | true 192 | true 193 | flutter_windows.dll.lib;%(AdditionalDependencies) 194 | $(FLUTTER_EPHEMERAL_DIR);$(OutDir)..\Plugins;%(AdditionalLibraryDirectories) 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | "$(ProjectDir)scripts\bundle_assets_and_deps" "$(FLUTTER_EPHEMERAL_DIR)\" "$(OutputPath)" "$(OutputPath)..\Plugins\" "$(TargetFileName)" 218 | 219 | 220 | Bundling dependencies 221 | Dummy_Run_Always 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | $(SolutionDir) 259 | 260 | 261 | -------------------------------------------------------------------------------- /windows/Runner.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {2761a4b5-57b2-4d50-a677-d20ddc17a7f1} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files\Client Wrapper 41 | 42 | 43 | Source Files\Client Wrapper 44 | 45 | 46 | Source Files\Client Wrapper 47 | 48 | 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | Resource Files 75 | 76 | 77 | 78 | 79 | Resource Files 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /windows/flutter/.template_version: -------------------------------------------------------------------------------- 1 | 2 2 | -------------------------------------------------------------------------------- /windows/flutter/GeneratedPlugins.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #include "generated_plugin_registrant.h" 6 | 7 | 8 | void RegisterPlugins(flutter::PluginRegistry* registry) { 9 | } 10 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 6 | #define GENERATED_PLUGIN_REGISTRANT_ 7 | 8 | #include 9 | 10 | // Registers Flutter plugins. 11 | void RegisterPlugins(flutter::PluginRegistry* registry); 12 | 13 | #endif // GENERATED_PLUGIN_REGISTRANT_ 14 | -------------------------------------------------------------------------------- /windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | #endif // English (United States) resources 58 | ///////////////////////////////////////////////////////////////////////////// 59 | 60 | 61 | 62 | #ifndef APSTUDIO_INVOKED 63 | ///////////////////////////////////////////////////////////////////////////// 64 | // 65 | // Generated from the TEXTINCLUDE 3 resource. 66 | // 67 | 68 | 69 | ///////////////////////////////////////////////////////////////////////////// 70 | #endif // not APSTUDIO_INVOKED 71 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include "flutter/generated_plugin_registrant.h" 4 | 5 | FlutterWindow::FlutterWindow(RunLoop* run_loop, 6 | const flutter::DartProject& project) 7 | : run_loop_(run_loop), project_(project) {} 8 | 9 | FlutterWindow::~FlutterWindow() {} 10 | 11 | void FlutterWindow::OnCreate() { 12 | Win32Window::OnCreate(); 13 | 14 | // The size here is arbitrary since SetChildContent will resize it. 15 | flutter_controller_ = 16 | std::make_unique(100, 100, project_); 17 | RegisterPlugins(flutter_controller_.get()); 18 | run_loop_->RegisterFlutterInstance(flutter_controller_.get()); 19 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 20 | } 21 | 22 | void FlutterWindow::OnDestroy() { 23 | if (flutter_controller_) { 24 | run_loop_->UnregisterFlutterInstance(flutter_controller_.get()); 25 | flutter_controller_ = nullptr; 26 | } 27 | 28 | Win32Window::OnDestroy(); 29 | } 30 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_WINDOW_H_ 2 | #define FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "run_loop.h" 8 | #include "win32_window.h" 9 | 10 | #include 11 | 12 | // A window that does nothing but host a Flutter view. 13 | class FlutterWindow : public Win32Window { 14 | public: 15 | // Creates a new FlutterWindow driven by the |run_loop|, hosting a 16 | // Flutter view running |project|. 17 | explicit FlutterWindow(RunLoop* run_loop, 18 | const flutter::DartProject& project); 19 | virtual ~FlutterWindow(); 20 | 21 | protected: 22 | // Win32Window: 23 | void OnCreate() override; 24 | void OnDestroy() override; 25 | 26 | private: 27 | // The run loop driving events for this window. 28 | RunLoop* run_loop_; 29 | 30 | // The project to run. 31 | flutter::DartProject project_; 32 | 33 | // The Flutter instance hosted by this window. 34 | std::unique_ptr flutter_controller_; 35 | }; 36 | 37 | #endif // FLUTTER_WINDOW_H_ 38 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "run_loop.h" 7 | #include "window_configuration.h" 8 | 9 | int APIENTRY wWinMain(_In_ HINSTANCE instance, 10 | _In_opt_ HINSTANCE prev, 11 | _In_ wchar_t* command_line, 12 | _In_ int show_command) { 13 | // Attach to console when present (e.g., 'flutter run') or create a 14 | // new console when running with a debugger. 15 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 16 | ::AllocConsole(); 17 | } 18 | 19 | // Initialize COM, so that it is available for use in the library and/or plugins. 20 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 21 | 22 | RunLoop run_loop; 23 | 24 | flutter::DartProject project(L"data"); 25 | FlutterWindow window(&run_loop, project); 26 | Win32Window::Point origin(kFlutterWindowOriginX, kFlutterWindowOriginY); 27 | Win32Window::Size size(kFlutterWindowWidth, kFlutterWindowHeight); 28 | if (!window.CreateAndShow(kFlutterWindowTitle, origin, size)) { 29 | return EXIT_FAILURE; 30 | } 31 | window.SetQuitOnClose(true); 32 | 33 | run_loop.Run(); 34 | 35 | ::CoUninitialize(); 36 | return EXIT_SUCCESS; 37 | } 38 | -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kechankrisna/flutter_wordpress/1b70d1965c20c1e553ac40cd8bfb6573a23d9194/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /windows/runner/run_loop.cpp: -------------------------------------------------------------------------------- 1 | #include "run_loop.h" 2 | 3 | #include 4 | // Don't stomp std::min/std::max 5 | #undef max 6 | #undef min 7 | 8 | #include 9 | 10 | RunLoop::RunLoop() {} 11 | 12 | RunLoop::~RunLoop() {} 13 | 14 | void RunLoop::Run() { 15 | bool keep_running = true; 16 | TimePoint next_flutter_event_time = TimePoint::clock::now(); 17 | while (keep_running) { 18 | std::chrono::nanoseconds wait_duration = 19 | std::max(std::chrono::nanoseconds(0), 20 | next_flutter_event_time - TimePoint::clock::now()); 21 | ::MsgWaitForMultipleObjects( 22 | 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000), 23 | QS_ALLINPUT); 24 | bool processed_events = false; 25 | MSG message; 26 | // All pending Windows messages must be processed; MsgWaitForMultipleObjects 27 | // won't return again for items left in the queue after PeekMessage. 28 | while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { 29 | processed_events = true; 30 | if (message.message == WM_QUIT) { 31 | keep_running = false; 32 | break; 33 | } 34 | ::TranslateMessage(&message); 35 | ::DispatchMessage(&message); 36 | // Allow Flutter to process messages each time a Windows message is 37 | // processed, to prevent starvation. 38 | next_flutter_event_time = 39 | std::min(next_flutter_event_time, ProcessFlutterMessages()); 40 | } 41 | // If the PeekMessage loop didn't run, process Flutter messages. 42 | if (!processed_events) { 43 | next_flutter_event_time = 44 | std::min(next_flutter_event_time, ProcessFlutterMessages()); 45 | } 46 | } 47 | } 48 | 49 | void RunLoop::RegisterFlutterInstance( 50 | flutter::FlutterViewController* flutter_instance) { 51 | flutter_instances_.insert(flutter_instance); 52 | } 53 | 54 | void RunLoop::UnregisterFlutterInstance( 55 | flutter::FlutterViewController* flutter_instance) { 56 | flutter_instances_.erase(flutter_instance); 57 | } 58 | 59 | RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { 60 | TimePoint next_event_time = TimePoint::max(); 61 | for (auto flutter_controller : flutter_instances_) { 62 | std::chrono::nanoseconds wait_duration = 63 | flutter_controller->ProcessMessages(); 64 | if (wait_duration != std::chrono::nanoseconds::max()) { 65 | next_event_time = 66 | std::min(next_event_time, TimePoint::clock::now() + wait_duration); 67 | } 68 | } 69 | return next_event_time; 70 | } 71 | -------------------------------------------------------------------------------- /windows/runner/run_loop.h: -------------------------------------------------------------------------------- 1 | #ifndef RUN_LOOP_H_ 2 | #define RUN_LOOP_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | // A runloop that will service events for Flutter instances as well 10 | // as native messages. 11 | class RunLoop { 12 | public: 13 | RunLoop(); 14 | ~RunLoop(); 15 | 16 | // Prevent copying 17 | RunLoop(RunLoop const&) = delete; 18 | RunLoop& operator=(RunLoop const&) = delete; 19 | 20 | // Runs the run loop until the application quits. 21 | void Run(); 22 | 23 | // Registers the given Flutter instance for event servicing. 24 | void RegisterFlutterInstance( 25 | flutter::FlutterViewController* flutter_instance); 26 | 27 | // Unregisters the given Flutter instance from event servicing. 28 | void UnregisterFlutterInstance( 29 | flutter::FlutterViewController* flutter_instance); 30 | 31 | private: 32 | using TimePoint = std::chrono::steady_clock::time_point; 33 | 34 | // Processes all currently pending messages for registered Flutter instances. 35 | TimePoint ProcessFlutterMessages(); 36 | 37 | std::set flutter_instances_; 38 | }; 39 | 40 | #endif // RUN_LOOP_H_ 41 | -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /windows/runner/win32_window.cpp: -------------------------------------------------------------------------------- 1 | #include "win32_window.h" 2 | 3 | #include 4 | 5 | #include "resource.h" 6 | 7 | namespace { 8 | 9 | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; 10 | 11 | // The number of Win32Window objects that currently exist. 12 | static int g_active_window_count = 0; 13 | 14 | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); 15 | 16 | // Scale helper to convert logical scaler values to physical using passed in 17 | // scale factor 18 | int Scale(int source, double scale_factor) { 19 | return static_cast(source * scale_factor); 20 | } 21 | 22 | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. 23 | // This API is only needed for PerMonitor V1 awareness mode. 24 | void EnableFullDpiSupportIfAvailable(HWND hwnd) { 25 | HMODULE user32_module = LoadLibraryA("User32.dll"); 26 | if (!user32_module) { 27 | return; 28 | } 29 | auto enable_non_client_dpi_scaling = 30 | reinterpret_cast( 31 | GetProcAddress(user32_module, "EnableNonClientDpiScaling")); 32 | if (enable_non_client_dpi_scaling != nullptr) { 33 | enable_non_client_dpi_scaling(hwnd); 34 | FreeLibrary(user32_module); 35 | } 36 | } 37 | 38 | } // namespace 39 | 40 | // Manages the Win32Window's window class registration. 41 | class WindowClassRegistrar { 42 | public: 43 | ~WindowClassRegistrar() = default; 44 | 45 | // Returns the singleton registar instance. 46 | static WindowClassRegistrar* GetInstance() { 47 | if (!instance_) { 48 | instance_ = new WindowClassRegistrar(); 49 | } 50 | return instance_; 51 | } 52 | 53 | // Returns the name of the window class, registering the class if it hasn't 54 | // previously been registered. 55 | const wchar_t* GetWindowClass(); 56 | 57 | // Unregisters the window class. Should only be called if there are no 58 | // instances of the window. 59 | void UnregisterWindowClass(); 60 | 61 | private: 62 | WindowClassRegistrar() = default; 63 | 64 | static WindowClassRegistrar* instance_; 65 | 66 | bool class_registered_ = false; 67 | }; 68 | 69 | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; 70 | 71 | const wchar_t* WindowClassRegistrar::GetWindowClass() { 72 | if (!class_registered_) { 73 | WNDCLASS window_class{}; 74 | window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); 75 | window_class.lpszClassName = kWindowClassName; 76 | window_class.style = CS_HREDRAW | CS_VREDRAW; 77 | window_class.cbClsExtra = 0; 78 | window_class.cbWndExtra = 0; 79 | window_class.hInstance = GetModuleHandle(nullptr); 80 | window_class.hIcon = 81 | LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); 82 | window_class.hbrBackground = 0; 83 | window_class.lpszMenuName = nullptr; 84 | window_class.lpfnWndProc = Win32Window::WndProc; 85 | RegisterClass(&window_class); 86 | class_registered_ = true; 87 | } 88 | return kWindowClassName; 89 | } 90 | 91 | void WindowClassRegistrar::UnregisterWindowClass() { 92 | UnregisterClass(kWindowClassName, nullptr); 93 | class_registered_ = false; 94 | } 95 | 96 | Win32Window::Win32Window() { 97 | ++g_active_window_count; 98 | } 99 | 100 | Win32Window::~Win32Window() { 101 | --g_active_window_count; 102 | Destroy(); 103 | } 104 | 105 | bool Win32Window::CreateAndShow(const std::wstring& title, 106 | const Point& origin, 107 | const Size& size) { 108 | Destroy(); 109 | 110 | const wchar_t* window_class = 111 | WindowClassRegistrar::GetInstance()->GetWindowClass(); 112 | 113 | const POINT target_point = {static_cast(origin.x), 114 | static_cast(origin.y)}; 115 | HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); 116 | UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); 117 | double scale_factor = dpi / 96.0; 118 | 119 | HWND window = CreateWindow( 120 | window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 121 | Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), 122 | Scale(size.width, scale_factor), Scale(size.height, scale_factor), 123 | nullptr, nullptr, GetModuleHandle(nullptr), this); 124 | 125 | OnCreate(); 126 | 127 | return window != nullptr; 128 | } 129 | 130 | // static 131 | LRESULT CALLBACK Win32Window::WndProc(HWND const window, 132 | UINT const message, 133 | WPARAM const wparam, 134 | LPARAM const lparam) noexcept { 135 | if (message == WM_NCCREATE) { 136 | auto window_struct = reinterpret_cast(lparam); 137 | SetWindowLongPtr(window, GWLP_USERDATA, 138 | reinterpret_cast(window_struct->lpCreateParams)); 139 | 140 | auto that = static_cast(window_struct->lpCreateParams); 141 | EnableFullDpiSupportIfAvailable(window); 142 | that->window_handle_ = window; 143 | } else if (Win32Window* that = GetThisFromHandle(window)) { 144 | return that->MessageHandler(window, message, wparam, lparam); 145 | } 146 | 147 | return DefWindowProc(window, message, wparam, lparam); 148 | } 149 | 150 | LRESULT 151 | Win32Window::MessageHandler(HWND hwnd, 152 | UINT const message, 153 | WPARAM const wparam, 154 | LPARAM const lparam) noexcept { 155 | auto window = 156 | reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); 157 | 158 | if (window == nullptr) { 159 | return 0; 160 | } 161 | 162 | switch (message) { 163 | case WM_DESTROY: 164 | window_handle_ = nullptr; 165 | Destroy(); 166 | if (quit_on_close_) { 167 | PostQuitMessage(0); 168 | } 169 | return 0; 170 | 171 | case WM_DPICHANGED: { 172 | auto newRectSize = reinterpret_cast(lparam); 173 | LONG newWidth = newRectSize->right - newRectSize->left; 174 | LONG newHeight = newRectSize->bottom - newRectSize->top; 175 | 176 | SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, 177 | newHeight, SWP_NOZORDER | SWP_NOACTIVATE); 178 | 179 | return 0; 180 | } 181 | case WM_SIZE: 182 | RECT rect; 183 | GetClientRect(hwnd, &rect); 184 | if (child_content_ != nullptr) { 185 | // Size and position the child window. 186 | MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, 187 | rect.bottom - rect.top, TRUE); 188 | } 189 | return 0; 190 | 191 | case WM_ACTIVATE: 192 | if (child_content_ != nullptr) { 193 | SetFocus(child_content_); 194 | } 195 | return 0; 196 | 197 | // Messages that are directly forwarded to embedding. 198 | case WM_FONTCHANGE: 199 | SendMessage(child_content_, WM_FONTCHANGE, NULL, NULL); 200 | return 0; 201 | } 202 | 203 | return DefWindowProc(window_handle_, message, wparam, lparam); 204 | } 205 | 206 | void Win32Window::Destroy() { 207 | OnDestroy(); 208 | 209 | if (window_handle_) { 210 | DestroyWindow(window_handle_); 211 | window_handle_ = nullptr; 212 | } 213 | if (g_active_window_count == 0) { 214 | WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); 215 | } 216 | } 217 | 218 | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { 219 | return reinterpret_cast( 220 | GetWindowLongPtr(window, GWLP_USERDATA)); 221 | } 222 | 223 | void Win32Window::SetChildContent(HWND content) { 224 | child_content_ = content; 225 | SetParent(content, window_handle_); 226 | RECT frame; 227 | GetClientRect(window_handle_, &frame); 228 | 229 | MoveWindow(content, frame.left, frame.top, frame.right - frame.left, 230 | frame.bottom - frame.top, true); 231 | 232 | SetFocus(child_content_); 233 | } 234 | 235 | HWND Win32Window::GetHandle() { 236 | return window_handle_; 237 | } 238 | 239 | void Win32Window::SetQuitOnClose(bool quit_on_close) { 240 | quit_on_close_ = quit_on_close; 241 | } 242 | 243 | void Win32Window::OnCreate() { 244 | // No-op; provided for subclasses. 245 | } 246 | 247 | void Win32Window::OnDestroy() { 248 | // No-op; provided for subclasses. 249 | } 250 | -------------------------------------------------------------------------------- /windows/runner/win32_window.h: -------------------------------------------------------------------------------- 1 | #ifndef WIN32_WINDOW_H_ 2 | #define WIN32_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be 12 | // inherited from by classes that wish to specialize with custom 13 | // rendering and input handling 14 | class Win32Window { 15 | public: 16 | struct Point { 17 | unsigned int x; 18 | unsigned int y; 19 | Point(unsigned int x, unsigned int y) : x(x), y(y) {} 20 | }; 21 | 22 | struct Size { 23 | unsigned int width; 24 | unsigned int height; 25 | Size(unsigned int width, unsigned int height) 26 | : width(width), height(height) {} 27 | }; 28 | 29 | Win32Window(); 30 | virtual ~Win32Window(); 31 | 32 | // Creates and shows a win32 window with |title| and position and size using 33 | // |origin| and |size|. New windows are created on the default monitor. Window 34 | // sizes are specified to the OS in physical pixels, hence to ensure a 35 | // consistent size to will treat the width height passed in to this function 36 | // as logical pixels and scale to appropriate for the default monitor. Returns 37 | // true if the window was created successfully. 38 | bool CreateAndShow(const std::wstring& title, 39 | const Point& origin, 40 | const Size& size); 41 | 42 | // Release OS resources associated with window. 43 | void Destroy(); 44 | 45 | // Inserts |content| into the window tree. 46 | void SetChildContent(HWND content); 47 | 48 | // Returns the backing Window handle to enable clients to set icon and other 49 | // window properties. Returns nullptr if the window has been destroyed. 50 | HWND GetHandle(); 51 | 52 | // If true, closing this window will quit the application. 53 | void SetQuitOnClose(bool quit_on_close); 54 | 55 | protected: 56 | // Processes and route salient window messages for mouse handling, 57 | // size change and DPI. Delegates handling of these to member overloads that 58 | // inheriting classes can handle. 59 | virtual LRESULT MessageHandler(HWND window, 60 | UINT const message, 61 | WPARAM const wparam, 62 | LPARAM const lparam) noexcept; 63 | 64 | // Called when CreateAndShow is called, allowing subclass window-related 65 | // setup. 66 | virtual void OnCreate(); 67 | 68 | // Called when Destroy is called. 69 | virtual void OnDestroy(); 70 | 71 | private: 72 | friend class WindowClassRegistrar; 73 | 74 | // OS callback called by message pump. Handles the WM_NCCREATE message which 75 | // is passed when the non-client area is being created and enables automatic 76 | // non-client DPI scaling so that the non-client area automatically 77 | // responsponds to changes in DPI. All other messages are handled by 78 | // MessageHandler. 79 | static LRESULT CALLBACK WndProc(HWND const window, 80 | UINT const message, 81 | WPARAM const wparam, 82 | LPARAM const lparam) noexcept; 83 | 84 | // Retrieves a class instance pointer for |window| 85 | static Win32Window* GetThisFromHandle(HWND const window) noexcept; 86 | 87 | bool quit_on_close_ = false; 88 | 89 | // window handle for top level window. 90 | HWND window_handle_ = nullptr; 91 | 92 | // window handle for hosted content. 93 | HWND child_content_ = nullptr; 94 | }; 95 | 96 | #endif // WIN32_WINDOW_H_ 97 | -------------------------------------------------------------------------------- /windows/runner/window_configuration.cpp: -------------------------------------------------------------------------------- 1 | #include "window_configuration.h" 2 | 3 | const wchar_t* kFlutterWindowTitle = L"flutter_wordpress"; 4 | const unsigned int kFlutterWindowOriginX = 10; 5 | const unsigned int kFlutterWindowOriginY = 10; 6 | const unsigned int kFlutterWindowWidth = 800; 7 | const unsigned int kFlutterWindowHeight = 600; 8 | -------------------------------------------------------------------------------- /windows/runner/window_configuration.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_CONFIGURATION_ 2 | #define WINDOW_CONFIGURATION_ 3 | 4 | // This is a temporary approach to isolate changes that people are likely to 5 | // make to main.cpp, where the APIs are still in flux. This will reduce the 6 | // need to resolve conflicts or re-create changes slightly differently every 7 | // time the Windows Flutter API surface changes. 8 | // 9 | // Longer term there should be simpler configuration options for common 10 | // customizations like this, without requiring native code changes. 11 | 12 | extern const wchar_t* kFlutterWindowTitle; 13 | extern const unsigned int kFlutterWindowOriginX; 14 | extern const unsigned int kFlutterWindowOriginY; 15 | extern const unsigned int kFlutterWindowWidth; 16 | extern const unsigned int kFlutterWindowHeight; 17 | 18 | #endif // WINDOW_CONFIGURATION_ 19 | -------------------------------------------------------------------------------- /windows/scripts/bundle_assets_and_deps.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set FLUTTER_CACHE_DIR=%~1 4 | set BUNDLE_DIR=%~2 5 | set PLUGIN_DIR=%~3 6 | set EXE_NAME=%~4 7 | 8 | set DATA_DIR=%BUNDLE_DIR%data 9 | 10 | if not exist "%DATA_DIR%" call mkdir "%DATA_DIR%" 11 | if %errorlevel% neq 0 exit /b %errorlevel% 12 | 13 | :: Write the executable name to the location expected by the Flutter tool. 14 | echo %EXE_NAME%>"%FLUTTER_CACHE_DIR%exe_filename" 15 | 16 | :: Copy the Flutter assets to the data directory. 17 | set FLUTTER_APP_DIR=%~dp0..\.. 18 | set ASSET_DIR_NAME=flutter_assets 19 | set TARGET_ASSET_DIR=%DATA_DIR%\%ASSET_DIR_NAME% 20 | if exist "%TARGET_ASSET_DIR%" call rmdir /s /q "%TARGET_ASSET_DIR%" 21 | if %errorlevel% neq 0 exit /b %errorlevel% 22 | call xcopy /s /e /i /q "%FLUTTER_APP_DIR%\build\%ASSET_DIR_NAME%" "%TARGET_ASSET_DIR%" 23 | if %errorlevel% neq 0 exit /b %errorlevel% 24 | 25 | :: Copy the icudtl.dat file from the Flutter tree to the data directory. 26 | call xcopy /y /d /q "%FLUTTER_CACHE_DIR%icudtl.dat" "%DATA_DIR%" 27 | if %errorlevel% neq 0 exit /b %errorlevel% 28 | 29 | :: Copy the Flutter DLL to the target location. 30 | call xcopy /y /d /q "%FLUTTER_CACHE_DIR%flutter_windows.dll" "%BUNDLE_DIR%" 31 | if %errorlevel% neq 0 exit /b %errorlevel% 32 | 33 | :: Copy any Plugin DLLs to the target location. 34 | if exist "%PLUGIN_DIR%" ( 35 | call xcopy /y /d /q "%PLUGIN_DIR%"*.dll "%BUNDLE_DIR%" 36 | if %errorlevel% neq 0 exit /b %errorlevel% 37 | ) 38 | -------------------------------------------------------------------------------- /windows/scripts/prepare_dependencies.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | :: Run flutter tool backend. 4 | set BUILD_MODE=%~1 5 | "%FLUTTER_ROOT%\packages\flutter_tools\bin\tool_backend" windows-x64 %BUILD_MODE% 6 | --------------------------------------------------------------------------------