├── .flutter-plugins
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── adhara_markdown.iml
├── android
├── app
│ └── src
│ │ └── main
│ │ └── java
│ │ └── io
│ │ └── flutter
│ │ └── plugins
│ │ └── GeneratedPluginRegistrant.java
└── local.properties
├── example
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── example
│ │ │ │ └── MainActivity.java
│ │ │ └── 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
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── ios
│ ├── .gitignore
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── flutter_export_environment.sh
│ ├── Podfile
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── Runner
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── 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
│ │ └── main.m
├── lib
│ └── main.dart
├── pubspec.yaml
└── test
│ └── widget_test.dart
├── lib
├── adhara_markdown.dart
├── mdbean.dart
├── mdeditor.dart
├── mdviewer.dart
└── utils.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── adhara_markdown_test.dart
/.flutter-plugins:
--------------------------------------------------------------------------------
1 | url_launcher=/Users/rohit/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-4.2.0/
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 | ios/.generated/
9 | ios/Flutter/Generated.xcconfig
10 | ios/Runner/GeneratedPluginRegistrant.*
11 |
12 | .idea/
13 |
--------------------------------------------------------------------------------
/.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: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
8 | channel: stable
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.2.0] - 26 Mar, 2020
2 |
3 | * Upgrade project to support new flutter releases (by [sbu-WBT(https://github.com/sbu-WBT))
4 |
5 | ## [0.1.2] - 5th April, 2019
6 |
7 | * Fix for optional parameter [PR3](https://github.com/infitio/flutter_markdown/pull/3)
8 |
9 | ## [0.1.1] - 23rd October, 2019
10 |
11 | * Upgrade dependencies
12 |
13 |
14 | ## [0.1.0] - 08th Feb, 2019
15 |
16 | * Minimalistic, highly customizable, regexp based markdown editor and viewer by adhara
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2021 Rohit R. Abbadi
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # adhara_markdown
2 |
3 | Minimalistic, highly customizable markdown editor and viewer by adhara
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Dart
8 | [package](https://flutter.io/developing-packages/),
9 | a library module containing code that can be shared easily across
10 | multiple Flutter or Dart projects.
11 |
12 | For help getting started with Flutter, view our
13 | [online documentation](https://flutter.io/docs), which offers tutorials,
14 | samples, guidance on mobile development, and a full API reference.
15 |
--------------------------------------------------------------------------------
/adhara_markdown.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java:
--------------------------------------------------------------------------------
1 | package io.flutter.plugins;
2 |
3 | import io.flutter.plugin.common.PluginRegistry;
4 | import io.flutter.plugins.urllauncher.UrlLauncherPlugin;
5 |
6 | /**
7 | * Generated file. Do not edit.
8 | */
9 | public final class GeneratedPluginRegistrant {
10 | public static void registerWith(PluginRegistry registry) {
11 | if (alreadyRegisteredWith(registry)) {
12 | return;
13 | }
14 | UrlLauncherPlugin.registerWith(registry.registrarFor("io.flutter.plugins.urllauncher.UrlLauncherPlugin"));
15 | }
16 |
17 | private static boolean alreadyRegisteredWith(PluginRegistry registry) {
18 | final String key = GeneratedPluginRegistrant.class.getCanonicalName();
19 | if (registry.hasPlugin(key)) {
20 | return true;
21 | }
22 | registry.registrarFor(key);
23 | return false;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android/local.properties:
--------------------------------------------------------------------------------
1 | sdk.dir=/Users/rohit/Library/Android/sdk
2 | flutter.sdk=/Users/rohit/flutter
3 | flutter.versionName=0.0.1
--------------------------------------------------------------------------------
/example/.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 |
--------------------------------------------------------------------------------
/example/.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: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # example
2 |
3 | A new Flutter project.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.io/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 |
--------------------------------------------------------------------------------
/example/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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26 |
27 | android {
28 | compileSdkVersion 30
29 |
30 | lintOptions {
31 | disable 'InvalidPackage'
32 | }
33 |
34 | defaultConfig {
35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
36 | applicationId "com.example.example"
37 | minSdkVersion 16
38 | targetSdkVersion 30
39 | versionCode flutterVersionCode.toInteger()
40 | versionName flutterVersionName
41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
42 | }
43 |
44 | buildTypes {
45 | release {
46 | // TODO: Add your own signing config for the release build.
47 | // Signing with the debug keys for now, so `flutter run --release` works.
48 | signingConfig signingConfigs.debug
49 | }
50 | }
51 | }
52 |
53 | flutter {
54 | source '../..'
55 | }
56 |
57 | dependencies {
58 | testImplementation 'junit:junit:4.12'
59 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
61 | }
62 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
15 |
19 |
26 |
30 |
34 |
39 |
43 |
44 |
45 |
46 |
47 |
48 |
50 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.example;
2 |
3 | import io.flutter.embedding.android.FlutterActivity;
4 |
5 | public class MainActivity extends FlutterActivity {
6 | }
7 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:4.1.2'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | android.enableR8=true
5 |
--------------------------------------------------------------------------------
/example/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-6.8.3-all.zip
7 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/example/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 |
--------------------------------------------------------------------------------
/example/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 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/example/ios/Flutter/flutter_export_environment.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # This is a generated file; do not edit or check into version control.
3 | export "FLUTTER_ROOT=/Users/rohit/flutter"
4 | export "FLUTTER_APPLICATION_PATH=/Users/rohit/workspace/opensource/adhara_markdown/example"
5 | export "FLUTTER_TARGET=lib/main.dart"
6 | export "FLUTTER_BUILD_DIR=build"
7 | export "SYMROOT=${SOURCE_ROOT}/../build/ios"
8 | export "FLUTTER_FRAMEWORK_DIR=/Users/rohit/flutter/bin/cache/artifacts/engine/ios"
9 | export "FLUTTER_BUILD_NAME=0.0.1"
10 | export "FLUTTER_BUILD_NUMBER=0.0.1"
11 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Using a CDN with CocoaPods 1.7.2 or later can save a lot of time on pod installation, but it's experimental rather than the default.
2 | # source 'https://cdn.cocoapods.org/'
3 |
4 | # Uncomment this line to define a global platform for your project
5 | # platform :ios, '9.0'
6 |
7 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
8 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
9 |
10 | project 'Runner', {
11 | 'Debug' => :debug,
12 | 'Profile' => :release,
13 | 'Release' => :release,
14 | }
15 |
16 | def parse_KV_file(file, separator='=')
17 | file_abs_path = File.expand_path(file)
18 | if !File.exists? file_abs_path
19 | return [];
20 | end
21 | pods_ary = []
22 | skip_line_start_symbols = ["#", "/"]
23 | File.foreach(file_abs_path) { |line|
24 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
25 | plugin = line.split(pattern=separator)
26 | if plugin.length == 2
27 | podname = plugin[0].strip()
28 | path = plugin[1].strip()
29 | podpath = File.expand_path("#{path}", file_abs_path)
30 | pods_ary.push({:name => podname, :path => podpath});
31 | else
32 | puts "Invalid plugin specification: #{line}"
33 | end
34 | }
35 | return pods_ary
36 | end
37 |
38 | target 'Runner' do
39 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
40 | # referring to absolute paths on developers' machines.
41 | system('rm -rf .symlinks')
42 | system('mkdir -p .symlinks/plugins')
43 |
44 | # Flutter Pods
45 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
46 | if generated_xcode_build_settings.empty?
47 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
48 | end
49 | generated_xcode_build_settings.map { |p|
50 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
51 | symlink = File.join('.symlinks', 'flutter')
52 | File.symlink(File.dirname(p[:path]), symlink)
53 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
54 | end
55 | }
56 |
57 | # Plugin Pods
58 | plugin_pods = parse_KV_file('../.flutter-plugins')
59 | plugin_pods.map { |p|
60 | symlink = File.join('.symlinks', 'plugins', p[:name])
61 | File.symlink(p[:path], symlink)
62 | pod p[:name], :path => File.join(symlink, 'ios')
63 | }
64 | end
65 |
66 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
67 | install! 'cocoapods', :disable_input_output_paths => true
68 |
69 | post_install do |installer|
70 | installer.pods_project.targets.each do |target|
71 | target.build_configurations.each do |config|
72 | config.build_settings['ENABLE_BITCODE'] = 'NO'
73 | end
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
14 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
18 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
19 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
20 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
21 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
22 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXCopyFilesBuildPhase section */
26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
27 | isa = PBXCopyFilesBuildPhase;
28 | buildActionMask = 2147483647;
29 | dstPath = "";
30 | dstSubfolderSpec = 10;
31 | files = (
32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
34 | );
35 | name = "Embed Frameworks";
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXCopyFilesBuildPhase section */
39 |
40 | /* Begin PBXFileReference section */
41 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
42 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
43 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
46 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
47 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
48 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
49 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
50 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
51 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
52 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
53 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
66 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | /* End PBXFrameworksBuildPhase section */
71 |
72 | /* Begin PBXGroup section */
73 | 9740EEB11CF90186004384FC /* Flutter */ = {
74 | isa = PBXGroup;
75 | children = (
76 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
77 | 3B80C3931E831B6300D905FE /* App.framework */,
78 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
79 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
81 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
82 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
83 | );
84 | name = Flutter;
85 | sourceTree = "";
86 | };
87 | 97C146E51CF9000F007C117D = {
88 | isa = PBXGroup;
89 | children = (
90 | 9740EEB11CF90186004384FC /* Flutter */,
91 | 97C146F01CF9000F007C117D /* Runner */,
92 | 97C146EF1CF9000F007C117D /* Products */,
93 | CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
94 | );
95 | sourceTree = "";
96 | };
97 | 97C146EF1CF9000F007C117D /* Products */ = {
98 | isa = PBXGroup;
99 | children = (
100 | 97C146EE1CF9000F007C117D /* Runner.app */,
101 | );
102 | name = Products;
103 | sourceTree = "";
104 | };
105 | 97C146F01CF9000F007C117D /* Runner */ = {
106 | isa = PBXGroup;
107 | children = (
108 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
109 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
110 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
111 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
112 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
113 | 97C147021CF9000F007C117D /* Info.plist */,
114 | 97C146F11CF9000F007C117D /* Supporting Files */,
115 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
116 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
117 | );
118 | path = Runner;
119 | sourceTree = "";
120 | };
121 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 97C146F21CF9000F007C117D /* main.m */,
125 | );
126 | name = "Supporting Files";
127 | sourceTree = "";
128 | };
129 | /* End PBXGroup section */
130 |
131 | /* Begin PBXNativeTarget section */
132 | 97C146ED1CF9000F007C117D /* Runner */ = {
133 | isa = PBXNativeTarget;
134 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
135 | buildPhases = (
136 | 9740EEB61CF901F6004384FC /* Run Script */,
137 | 97C146EA1CF9000F007C117D /* Sources */,
138 | 97C146EB1CF9000F007C117D /* Frameworks */,
139 | 97C146EC1CF9000F007C117D /* Resources */,
140 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
142 | );
143 | buildRules = (
144 | );
145 | dependencies = (
146 | );
147 | name = Runner;
148 | productName = Runner;
149 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
150 | productType = "com.apple.product-type.application";
151 | };
152 | /* End PBXNativeTarget section */
153 |
154 | /* Begin PBXProject section */
155 | 97C146E61CF9000F007C117D /* Project object */ = {
156 | isa = PBXProject;
157 | attributes = {
158 | LastUpgradeCheck = 0910;
159 | ORGANIZATIONNAME = "The Chromium Authors";
160 | TargetAttributes = {
161 | 97C146ED1CF9000F007C117D = {
162 | CreatedOnToolsVersion = 7.3.1;
163 | };
164 | };
165 | };
166 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
167 | compatibilityVersion = "Xcode 3.2";
168 | developmentRegion = English;
169 | hasScannedForEncodings = 0;
170 | knownRegions = (
171 | en,
172 | Base,
173 | );
174 | mainGroup = 97C146E51CF9000F007C117D;
175 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
176 | projectDirPath = "";
177 | projectRoot = "";
178 | targets = (
179 | 97C146ED1CF9000F007C117D /* Runner */,
180 | );
181 | };
182 | /* End PBXProject section */
183 |
184 | /* Begin PBXResourcesBuildPhase section */
185 | 97C146EC1CF9000F007C117D /* Resources */ = {
186 | isa = PBXResourcesBuildPhase;
187 | buildActionMask = 2147483647;
188 | files = (
189 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
190 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
191 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
192 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
193 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXResourcesBuildPhase section */
199 |
200 | /* Begin PBXShellScriptBuildPhase section */
201 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
202 | isa = PBXShellScriptBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | );
206 | inputPaths = (
207 | );
208 | name = "Thin Binary";
209 | outputPaths = (
210 | );
211 | runOnlyForDeploymentPostprocessing = 0;
212 | shellPath = /bin/sh;
213 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
214 | };
215 | 9740EEB61CF901F6004384FC /* Run Script */ = {
216 | isa = PBXShellScriptBuildPhase;
217 | buildActionMask = 2147483647;
218 | files = (
219 | );
220 | inputPaths = (
221 | );
222 | name = "Run Script";
223 | outputPaths = (
224 | );
225 | runOnlyForDeploymentPostprocessing = 0;
226 | shellPath = /bin/sh;
227 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
228 | };
229 | /* End PBXShellScriptBuildPhase section */
230 |
231 | /* Begin PBXSourcesBuildPhase section */
232 | 97C146EA1CF9000F007C117D /* Sources */ = {
233 | isa = PBXSourcesBuildPhase;
234 | buildActionMask = 2147483647;
235 | files = (
236 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
237 | 97C146F31CF9000F007C117D /* main.m in Sources */,
238 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
239 | );
240 | runOnlyForDeploymentPostprocessing = 0;
241 | };
242 | /* End PBXSourcesBuildPhase section */
243 |
244 | /* Begin PBXVariantGroup section */
245 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
246 | isa = PBXVariantGroup;
247 | children = (
248 | 97C146FB1CF9000F007C117D /* Base */,
249 | );
250 | name = Main.storyboard;
251 | sourceTree = "";
252 | };
253 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
254 | isa = PBXVariantGroup;
255 | children = (
256 | 97C147001CF9000F007C117D /* Base */,
257 | );
258 | name = LaunchScreen.storyboard;
259 | sourceTree = "";
260 | };
261 | /* End PBXVariantGroup section */
262 |
263 | /* Begin XCBuildConfiguration section */
264 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
265 | isa = XCBuildConfiguration;
266 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
267 | buildSettings = {
268 | ALWAYS_SEARCH_USER_PATHS = NO;
269 | CLANG_ANALYZER_NONNULL = YES;
270 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
271 | CLANG_CXX_LIBRARY = "libc++";
272 | CLANG_ENABLE_MODULES = YES;
273 | CLANG_ENABLE_OBJC_ARC = YES;
274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
275 | CLANG_WARN_BOOL_CONVERSION = YES;
276 | CLANG_WARN_COMMA = YES;
277 | CLANG_WARN_CONSTANT_CONVERSION = YES;
278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
279 | CLANG_WARN_EMPTY_BODY = YES;
280 | CLANG_WARN_ENUM_CONVERSION = YES;
281 | CLANG_WARN_INFINITE_RECURSION = YES;
282 | CLANG_WARN_INT_CONVERSION = YES;
283 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
284 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
286 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
287 | CLANG_WARN_STRICT_PROTOTYPES = YES;
288 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
289 | CLANG_WARN_UNREACHABLE_CODE = YES;
290 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
291 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
292 | COPY_PHASE_STRIP = NO;
293 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
294 | ENABLE_NS_ASSERTIONS = NO;
295 | ENABLE_STRICT_OBJC_MSGSEND = YES;
296 | GCC_C_LANGUAGE_STANDARD = gnu99;
297 | GCC_NO_COMMON_BLOCKS = YES;
298 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
299 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
300 | GCC_WARN_UNDECLARED_SELECTOR = YES;
301 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
302 | GCC_WARN_UNUSED_FUNCTION = YES;
303 | GCC_WARN_UNUSED_VARIABLE = YES;
304 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
305 | MTL_ENABLE_DEBUG_INFO = NO;
306 | SDKROOT = iphoneos;
307 | TARGETED_DEVICE_FAMILY = "1,2";
308 | VALIDATE_PRODUCT = YES;
309 | };
310 | name = Profile;
311 | };
312 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
313 | isa = XCBuildConfiguration;
314 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
315 | buildSettings = {
316 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
317 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
318 | DEVELOPMENT_TEAM = S8QB4VV633;
319 | ENABLE_BITCODE = NO;
320 | FRAMEWORK_SEARCH_PATHS = (
321 | "$(inherited)",
322 | "$(PROJECT_DIR)/Flutter",
323 | );
324 | INFOPLIST_FILE = Runner/Info.plist;
325 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
326 | LIBRARY_SEARCH_PATHS = (
327 | "$(inherited)",
328 | "$(PROJECT_DIR)/Flutter",
329 | );
330 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
331 | PRODUCT_NAME = "$(TARGET_NAME)";
332 | VERSIONING_SYSTEM = "apple-generic";
333 | };
334 | name = Profile;
335 | };
336 | 97C147031CF9000F007C117D /* Debug */ = {
337 | isa = XCBuildConfiguration;
338 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
339 | buildSettings = {
340 | ALWAYS_SEARCH_USER_PATHS = NO;
341 | CLANG_ANALYZER_NONNULL = YES;
342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
343 | CLANG_CXX_LIBRARY = "libc++";
344 | CLANG_ENABLE_MODULES = YES;
345 | CLANG_ENABLE_OBJC_ARC = YES;
346 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
347 | CLANG_WARN_BOOL_CONVERSION = YES;
348 | CLANG_WARN_COMMA = YES;
349 | CLANG_WARN_CONSTANT_CONVERSION = YES;
350 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
351 | CLANG_WARN_EMPTY_BODY = YES;
352 | CLANG_WARN_ENUM_CONVERSION = YES;
353 | CLANG_WARN_INFINITE_RECURSION = YES;
354 | CLANG_WARN_INT_CONVERSION = YES;
355 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
356 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
357 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
358 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
359 | CLANG_WARN_STRICT_PROTOTYPES = YES;
360 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
361 | CLANG_WARN_UNREACHABLE_CODE = YES;
362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
363 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
364 | COPY_PHASE_STRIP = NO;
365 | DEBUG_INFORMATION_FORMAT = dwarf;
366 | ENABLE_STRICT_OBJC_MSGSEND = YES;
367 | ENABLE_TESTABILITY = YES;
368 | GCC_C_LANGUAGE_STANDARD = gnu99;
369 | GCC_DYNAMIC_NO_PIC = NO;
370 | GCC_NO_COMMON_BLOCKS = YES;
371 | GCC_OPTIMIZATION_LEVEL = 0;
372 | GCC_PREPROCESSOR_DEFINITIONS = (
373 | "DEBUG=1",
374 | "$(inherited)",
375 | );
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
383 | MTL_ENABLE_DEBUG_INFO = YES;
384 | ONLY_ACTIVE_ARCH = YES;
385 | SDKROOT = iphoneos;
386 | TARGETED_DEVICE_FAMILY = "1,2";
387 | };
388 | name = Debug;
389 | };
390 | 97C147041CF9000F007C117D /* Release */ = {
391 | isa = XCBuildConfiguration;
392 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
393 | buildSettings = {
394 | ALWAYS_SEARCH_USER_PATHS = NO;
395 | CLANG_ANALYZER_NONNULL = YES;
396 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
397 | CLANG_CXX_LIBRARY = "libc++";
398 | CLANG_ENABLE_MODULES = YES;
399 | CLANG_ENABLE_OBJC_ARC = YES;
400 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
401 | CLANG_WARN_BOOL_CONVERSION = YES;
402 | CLANG_WARN_COMMA = YES;
403 | CLANG_WARN_CONSTANT_CONVERSION = YES;
404 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
405 | CLANG_WARN_EMPTY_BODY = YES;
406 | CLANG_WARN_ENUM_CONVERSION = YES;
407 | CLANG_WARN_INFINITE_RECURSION = YES;
408 | CLANG_WARN_INT_CONVERSION = YES;
409 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
410 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
411 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
412 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
413 | CLANG_WARN_STRICT_PROTOTYPES = YES;
414 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
415 | CLANG_WARN_UNREACHABLE_CODE = YES;
416 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
417 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
418 | COPY_PHASE_STRIP = NO;
419 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
420 | ENABLE_NS_ASSERTIONS = NO;
421 | ENABLE_STRICT_OBJC_MSGSEND = YES;
422 | GCC_C_LANGUAGE_STANDARD = gnu99;
423 | GCC_NO_COMMON_BLOCKS = YES;
424 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
425 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
426 | GCC_WARN_UNDECLARED_SELECTOR = YES;
427 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
428 | GCC_WARN_UNUSED_FUNCTION = YES;
429 | GCC_WARN_UNUSED_VARIABLE = YES;
430 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
431 | MTL_ENABLE_DEBUG_INFO = NO;
432 | SDKROOT = iphoneos;
433 | TARGETED_DEVICE_FAMILY = "1,2";
434 | VALIDATE_PRODUCT = YES;
435 | };
436 | name = Release;
437 | };
438 | 97C147061CF9000F007C117D /* Debug */ = {
439 | isa = XCBuildConfiguration;
440 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
441 | buildSettings = {
442 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
443 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
444 | ENABLE_BITCODE = NO;
445 | FRAMEWORK_SEARCH_PATHS = (
446 | "$(inherited)",
447 | "$(PROJECT_DIR)/Flutter",
448 | );
449 | INFOPLIST_FILE = Runner/Info.plist;
450 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
451 | LIBRARY_SEARCH_PATHS = (
452 | "$(inherited)",
453 | "$(PROJECT_DIR)/Flutter",
454 | );
455 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
456 | PRODUCT_NAME = "$(TARGET_NAME)";
457 | VERSIONING_SYSTEM = "apple-generic";
458 | };
459 | name = Debug;
460 | };
461 | 97C147071CF9000F007C117D /* Release */ = {
462 | isa = XCBuildConfiguration;
463 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
464 | buildSettings = {
465 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
466 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
467 | ENABLE_BITCODE = NO;
468 | FRAMEWORK_SEARCH_PATHS = (
469 | "$(inherited)",
470 | "$(PROJECT_DIR)/Flutter",
471 | );
472 | INFOPLIST_FILE = Runner/Info.plist;
473 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
474 | LIBRARY_SEARCH_PATHS = (
475 | "$(inherited)",
476 | "$(PROJECT_DIR)/Flutter",
477 | );
478 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
479 | PRODUCT_NAME = "$(TARGET_NAME)";
480 | VERSIONING_SYSTEM = "apple-generic";
481 | };
482 | name = Release;
483 | };
484 | /* End XCBuildConfiguration section */
485 |
486 | /* Begin XCConfigurationList section */
487 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
488 | isa = XCConfigurationList;
489 | buildConfigurations = (
490 | 97C147031CF9000F007C117D /* Debug */,
491 | 97C147041CF9000F007C117D /* Release */,
492 | 249021D3217E4FDB00AE95B9 /* Profile */,
493 | );
494 | defaultConfigurationIsVisible = 0;
495 | defaultConfigurationName = Release;
496 | };
497 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
498 | isa = XCConfigurationList;
499 | buildConfigurations = (
500 | 97C147061CF9000F007C117D /* Debug */,
501 | 97C147071CF9000F007C117D /* Release */,
502 | 249021D4217E4FDB00AE95B9 /* Profile */,
503 | );
504 | defaultConfigurationIsVisible = 0;
505 | defaultConfigurationName = Release;
506 | };
507 | /* End XCConfigurationList section */
508 | };
509 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
510 | }
511 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/example/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 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/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 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/infitio/flutter_markdown/28a93bf4f4d85d54850d5b4ce8d269e09b636d49/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/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.
--------------------------------------------------------------------------------
/example/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 |
--------------------------------------------------------------------------------
/example/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 |
--------------------------------------------------------------------------------
/example/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 | example
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 |
--------------------------------------------------------------------------------
/example/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:adhara_markdown/adhara_markdown.dart';
3 |
4 | main() => runApp(App());
5 |
6 | List storyPieces = [
7 | "There were once *two brothers* who lived on the *edge of a forest*."
8 | " The elder brother was very _mean_ to his younger brother and _ate up all the food and took all his good clothes_."
9 | " One day, the elder brother went into the forest to find some `firewood` to `sell in the market`."
10 | " As he went around chopping the branches of a tree after tree, he came upon a `magical tree`."
11 | " The tree said to him, 'Oh kind sir, please do not cut my branches. If you spare me, I will give you my golden apples'."
12 | " The elder brother agreed but was ~disappointed~ with the number apples the tree gave him. Greed overcame him, and he threatened to cut the entire trunk if the tree didn’t give him more apples. The magical tree instead showered upon the elder brother hundreds upon hundreds of tiny needles. The elder brother lay on the ground crying in pain as the sun began to lower down the horizon.",
13 | "*The younger brother grew worried and went in search of his elder brother.*"
14 | " He found him with hundreds of needles on his skin."
15 | " He rushed to his brother and removed each needle with painstaking love."
16 | " After he finished, the elder brother apologised for treating him badly and promised to be better."
17 | " The tree saw the change in the elder brother’s heart and gave them all the golden apples they could ever need."
18 | ];
19 |
20 | class App extends StatelessWidget {
21 | @override
22 | Widget build(BuildContext context) {
23 | return MaterialApp(
24 | debugShowCheckedModeBanner: false,
25 | home: HomePage(),
26 | theme: new ThemeData(
27 | primaryColor: Colors.blue, backgroundColor: Colors.white),
28 | color: Colors.blue);
29 | }
30 | }
31 |
32 | class HomePage extends StatefulWidget {
33 | @override
34 | State createState() => HomePageState();
35 | }
36 |
37 | class HomePageState extends State {
38 | int editingPiece = -1;
39 | MarkdownEditorController controller;
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | return Scaffold(
44 | appBar: AppBar(
45 | title: Text("MD Viewer & Editor"),
46 | actions: [
47 | IconButton(
48 | icon: Icon(
49 | Icons.info,
50 | color: Colors.white,
51 | ),
52 | onPressed: () {
53 | showAboutDialog(
54 | context: context,
55 | applicationName: "Adhara MD Editor",
56 | children: [
57 | Text(
58 | "How to use",
59 | style: TextStyle(
60 | fontWeight: FontWeight.bold, fontSize: 18.0),
61 | ),
62 | Text("Tap on the paragraphs to change to edit mode."),
63 | Text("edit and click on update FAB")
64 | ]);
65 | // showDialog(
66 | // context: context,
67 | // builder: (BuildContext context){
68 | // return Text("ad");
69 | // }
70 | // );
71 | })
72 | ],
73 | ),
74 | floatingActionButton: (editingPiece == -1)
75 | ? null
76 | : FloatingActionButton(
77 | child: Icon(Icons.check),
78 | onPressed: () {
79 | setState(() {
80 | storyPieces[editingPiece] = controller.text;
81 | editingPiece = -1;
82 | });
83 | },
84 | ),
85 | body: Container(
86 | padding: EdgeInsets.all(12.0),
87 | child: ListView(
88 | children: [
89 | _buildStory(storyPieces[0], 0),
90 | SizedBox(height: 8.0),
91 | _buildStory(storyPieces[1], 1)
92 | ],
93 | ),
94 | ),
95 | );
96 | }
97 |
98 | get textStyle => TextStyle(fontSize: 18.0, color: Colors.black);
99 | get highlightedTextStyle =>
100 | TextStyle(fontSize: 18.0, color: Colors.lightBlue);
101 |
102 | _buildStory(String storyPiece, int pieceIndex) {
103 | if (editingPiece == pieceIndex) {
104 | return _buildStoryEditor(storyPiece, pieceIndex);
105 | }
106 | return GestureDetector(
107 | child: MarkdownViewer(
108 | content: storyPiece,
109 | textStyle: textStyle,
110 | formatTypes: [
111 | MarkdownTokenTypes.bold,
112 | MarkdownTokenTypes.italic,
113 | MarkdownTokenTypes.strikeThrough,
114 | MarkdownTokenTypes.code
115 | ],
116 | ),
117 | onTap: () {
118 | setState(() {
119 | editingPiece = pieceIndex;
120 | });
121 | },
122 | );
123 | }
124 |
125 | _buildStoryEditor(String storyPiece, pieceIndex) {
126 | controller = MarkdownEditorController();
127 | return Container(
128 | child: Column(
129 | children: [
130 | MarkdownEditor(
131 | value: storyPiece,
132 | textStyle: TextStyle(fontSize: 18.0, color: Colors.black),
133 | controller: controller,
134 | tokenConfigs: [
135 | MarkdownTokenConfig.mention(textStyle: highlightedTextStyle),
136 | MarkdownTokenConfig.link(textStyle: highlightedTextStyle),
137 | MarkdownTokenConfig.hashTag(textStyle: highlightedTextStyle),
138 | ],
139 | ),
140 | ],
141 | ),
142 | );
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: adhara_markdown_example
2 | description: Minimalistic, highly customizable, regexp based markdown editor and viewer by adhara - Example
3 | version: 0.0.1
4 | author:
5 | homepage:
6 |
7 | publish_to: 'none'
8 |
9 | environment:
10 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
11 |
12 | dependencies:
13 | flutter:
14 | sdk: flutter
15 | adhara_markdown:
16 | path: ../
17 |
18 | dev_dependencies:
19 | flutter_test:
20 | sdk: flutter
21 |
22 | flutter:
23 | uses-material-design: true
24 |
--------------------------------------------------------------------------------
/example/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:example/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(MyApp());
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 |
--------------------------------------------------------------------------------
/lib/adhara_markdown.dart:
--------------------------------------------------------------------------------
1 | library adhara_markdown;
2 |
3 | export 'package:adhara_markdown/mdbean.dart';
4 | export 'package:adhara_markdown/mdeditor.dart';
5 | export 'package:adhara_markdown/mdviewer.dart';
6 | export 'package:adhara_markdown/utils.dart';
7 |
--------------------------------------------------------------------------------
/lib/mdbean.dart:
--------------------------------------------------------------------------------
1 | class MarkDownBean {
2 | String content;
3 | MarkdownMeta meta;
4 | }
5 |
6 | class MarkdownMeta {
7 | List collection;
8 |
9 | MarkdownMeta(this.collection) {
10 | if (collection == null) {
11 | collection = [];
12 | } else {
13 | collection.sort((SelectionInfo selection1, SelectionInfo selection2) =>
14 | selection1.startIndex.compareTo(selection2.startIndex));
15 | }
16 | }
17 |
18 | SelectionInfo selectionMeta(int user) => collection[user];
19 |
20 | add(int user, SelectionInfo meta) {
21 | collection[user] = meta;
22 | }
23 |
24 | remove(int user) {
25 | collection.remove(user);
26 | }
27 | }
28 |
29 | class SelectionInfo {
30 | int startIndex;
31 | int endIndex;
32 | dynamic data;
33 |
34 | SelectionInfo(this.startIndex, this.endIndex, this.data);
35 |
36 | void updateIndex(int newStartIndex) {
37 | this.endIndex += newStartIndex - this.startIndex;
38 | this.startIndex = newStartIndex;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/mdeditor.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:adhara_markdown/mdbean.dart';
3 | import 'package:adhara_markdown/mdviewer.dart';
4 | import 'package:adhara_markdown/utils.dart';
5 |
6 | class MarkdownEditor extends StatefulWidget {
7 | final String value;
8 | final String hint;
9 | final bool autoFocus;
10 | final OnSavedCallback onSaved;
11 | final List tokenConfigs;
12 | final TextStyle textStyle;
13 | final TextStyle highlightedTextStyle;
14 | final MarkDownBean bean;
15 | final MarkdownEditorController controller;
16 | final InputDecoration decoration;
17 | final FormFieldSetter onChange;
18 | final BoxConstraints suggestionsConstraints;
19 | final Offset suggestionsOffset;
20 |
21 | MarkdownEditor(
22 | {Key key,
23 | this.value,
24 | this.hint,
25 | this.autoFocus,
26 | this.onSaved,
27 | this.onChange,
28 | this.controller,
29 | this.tokenConfigs,
30 | this.textStyle,
31 | this.highlightedTextStyle,
32 | this.decoration,
33 | this.suggestionsConstraints,
34 | this.suggestionsOffset: Offset.zero,
35 | MarkDownBean bean})
36 | : bean = bean ?? MarkDownBean(),
37 | super(key: key);
38 |
39 | @override
40 | _MarkdownEditorState createState() => _MarkdownEditorState();
41 | }
42 |
43 | class _MarkdownEditorState extends State
44 | with WidgetsBindingObserver {
45 | TextEditingController textEditingController;
46 | int currentContentLength;
47 | Match match;
48 | List suggestions = [];
49 | MarkdownTokenConfig tokenConfig;
50 |
51 | TextStyle baseTextStyle = TextStyle(
52 | color: const Color(0xff273d52),
53 | fontWeight: FontWeight.w400,
54 | fontFamily: "SFProText",
55 | fontStyle: FontStyle.normal,
56 | fontSize: 14.0,
57 | );
58 |
59 | GlobalKey _editorKey = GlobalKey();
60 | OverlayState overlayState;
61 |
62 | @override
63 | void initState() {
64 | super.initState();
65 | textEditingController = TextEditingController(text: widget.value);
66 | WidgetsBinding.instance.addObserver(this);
67 | widget.controller?._state =
68 | this; //must be called after setting textEditingController
69 | currentContentLength = textEditingController.text.length;
70 | overlayState = Overlay.of(context);
71 | textEditingController.addListener(_listenTextInput);
72 | }
73 |
74 | InputDecoration get _decoration =>
75 | widget.decoration ??
76 | InputDecoration(
77 | contentPadding: EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0),
78 | hintText: widget.hint,
79 | hintStyle: baseTextStyle.copyWith(color: const Color(0x80273d52)),
80 | border: InputBorder.none,
81 | );
82 |
83 | @override
84 | Widget build(BuildContext context) {
85 | final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
86 | TextStyle effectiveTextStyle = widget.textStyle;
87 | if (widget.textStyle == null || widget.textStyle.inherit)
88 | effectiveTextStyle = defaultTextStyle.style.merge(widget.textStyle);
89 | double topOffset = _decoration.labelStyle?.fontSize ?? 0.0;
90 | if (_decoration.hintStyle != null) {
91 | topOffset += _decoration.hintStyle.fontSize - effectiveTextStyle.fontSize;
92 | }
93 | /*if(_decoration.contentPadding!=null){
94 | topOffset += _decoration.contentPadding.vertical/2;
95 | }*/
96 | return Stack(
97 | key: _editorKey,
98 | children: [
99 | //highlighted rich text
100 | Container(
101 | padding:
102 | _decoration.contentPadding?.add(EdgeInsets.only(top: topOffset)),
103 | child: MarkdownViewer(
104 | content: textEditingController.text,
105 | collapsible: false,
106 | textStyle: effectiveTextStyle,
107 | highlightedTextStyle: widget.highlightedTextStyle,
108 | tokenConfigs: widget.tokenConfigs,
109 | /*formatTypes: [
110 | MarkdownTokenTypes.link,
111 | MarkdownTokenTypes.mention,
112 | MarkdownTokenTypes.hashTag
113 | ]*/
114 | ),
115 | ),
116 | //Text input box
117 | TextFormField(
118 | controller: textEditingController,
119 | autofocus: widget.autoFocus ?? true,
120 | keyboardType: TextInputType.multiline,
121 | maxLines: null,
122 | style: effectiveTextStyle.copyWith(color: Colors.transparent),
123 | // style: effectiveTextStyle.copyWith(color: Colors.grey.withOpacity(0.1)),
124 | decoration: _decoration,
125 | onSaved: widget.onSaved),
126 | ],
127 | );
128 | }
129 |
130 | @override
131 | void didChangeMetrics() {
132 | _listenTextInput();
133 | }
134 |
135 | _listenTextInput() async {
136 | setState(() {
137 | suggestions = [];
138 | match = null;
139 | });
140 | if (textEditingController != null) {
141 | if (textEditingController.text.length < 1) {
142 | suggestions = [];
143 | for (MarkdownTokenConfig _tokenConfig in widget.tokenConfigs) {
144 | _tokenConfig.meta?.collection = [];
145 | }
146 | } else {
147 | int indexNow = textEditingController.selection.baseOffset - 1;
148 | if (indexNow < 0) return;
149 | for (MarkdownTokenConfig _tokenConfig in widget.tokenConfigs) {
150 | if (_tokenConfig.hintRegExp != null) {
151 | for (Match m in _tokenConfig.hintRegExp
152 | .allMatches(textEditingController.text)) {
153 | if (m.start < indexNow + 1 && m.end >= indexNow + 1) {
154 | if (_tokenConfig.suggestions != null) {
155 | suggestions = await _tokenConfig.suggestions(
156 | textEditingController.text
157 | .substring(m.start, indexNow + 1));
158 | } else {
159 | suggestions = [];
160 | }
161 | match = m;
162 | tokenConfig = _tokenConfig;
163 | break;
164 | }
165 | }
166 | if (match != null) break;
167 | }
168 | }
169 | // postMeta index update
170 | int textLength = textEditingController.text.length;
171 | if (currentContentLength != textEditingController.text.length) {
172 | for (MarkdownTokenConfig _tokenConfig in widget.tokenConfigs) {
173 | if (_tokenConfig.meta != null) {
174 | _tokenConfig.meta.collection.forEach((SelectionInfo info) {
175 | if (textLength > currentContentLength) {
176 | if (info.startIndex <=
177 | indexNow - (textLength - currentContentLength) &&
178 | indexNow - (textLength - currentContentLength) <
179 | info.endIndex) {
180 | _tokenConfig.meta.collection = _tokenConfig.meta.collection
181 | .where((selectionInfo) => selectionInfo != info)
182 | .toList();
183 | } else if (info.startIndex >
184 | indexNow - (textLength - currentContentLength)) {
185 | info.updateIndex(
186 | info.startIndex + (textLength - currentContentLength));
187 | }
188 | } else {
189 | if (info.startIndex - 1 <= indexNow &&
190 | indexNow < info.endIndex) {
191 | _tokenConfig.meta.collection = _tokenConfig.meta.collection
192 | .where((selectionInfo) => selectionInfo != info)
193 | .toList();
194 | } else if (info.startIndex - 1 > indexNow) {
195 | info.updateIndex(
196 | info.startIndex - (currentContentLength - textLength));
197 | }
198 | }
199 | });
200 | }
201 | }
202 | }
203 | }
204 | currentContentLength = textEditingController.text.length;
205 | setState(() {});
206 | }
207 | showSuggestions(context);
208 | if (widget.onChange != null) {
209 | widget.onChange(textEditingController.text);
210 | }
211 | }
212 |
213 | OverlayEntry overlaySuggestions;
214 | showSuggestions(BuildContext context) async {
215 | clearSuggestions();
216 | if (suggestions.length == 0) return;
217 | final RenderBox renderBoxRed = _editorKey.currentContext.findRenderObject();
218 | final editorSize = renderBoxRed.size;
219 | final editorPosition = renderBoxRed.localToGlobal(Offset.zero);
220 | double keyboardHeight = MediaQuery.of(context).viewInsets.bottom;
221 | double visibleHeight = MediaQuery.of(context).size.height - keyboardHeight;
222 | Offset suggestionOffset = widget.suggestionsOffset ?? Offset.zero;
223 | double top = editorPosition.dy + editorSize.height + suggestionOffset.dy;
224 | double bottom;
225 | if (top > visibleHeight / 2) {
226 | top = null;
227 | bottom = keyboardHeight + editorSize.height + suggestionOffset.dy;
228 | }
229 | print(
230 | "top $top bottom $bottom editorPosition.dy ${editorPosition.dy} visibleHeight $visibleHeight");
231 | overlaySuggestions = OverlayEntry(
232 | builder: (context) => Positioned(
233 | top: top,
234 | bottom: bottom,
235 | left: suggestionOffset.dx,
236 | child: _buildSuggestions(context),
237 | ));
238 | overlayState.insert(overlaySuggestions);
239 | }
240 |
241 | clearSuggestions() {
242 | overlaySuggestions?.remove();
243 | overlaySuggestions = null;
244 | }
245 |
246 | Widget _buildSuggestions(BuildContext context) {
247 | if (suggestions.isNotEmpty) {
248 | return Material(
249 | child: ConstrainedBox(
250 | constraints: widget.suggestionsConstraints ??
251 | BoxConstraints(
252 | maxWidth: MediaQuery.of(context).size.width,
253 | maxHeight: 400.0),
254 | child: Container(
255 | decoration: BoxDecoration(
256 | color: Colors.transparent,
257 | border: Border.all(color: const Color(0x32273d52)),
258 | borderRadius: BorderRadius.circular(4.0)),
259 | child: _buildSuggestionsList(),
260 | )));
261 | }
262 | return Container();
263 | }
264 |
265 | ListView _buildSuggestionsList() {
266 | return ListView(
267 | padding: EdgeInsets.zero,
268 | shrinkWrap: true,
269 | children: suggestions.map((TokenSuggestion suggestion) {
270 | return InkWell(child: Builder(builder: (BuildContext context) {
271 | return suggestion.display;
272 | }), onTap: () {
273 | int indexNow = textEditingController.selection.baseOffset;
274 | int indexAt = match.start;
275 | String addToInput = suggestion.onInsert();
276 | int offSet = indexAt + 1;
277 | textEditingController.text =
278 | textEditingController.text.substring(0, indexAt) +
279 | addToInput +
280 | textEditingController.text.substring(indexNow);
281 | offSet = offSet + addToInput.length;
282 | textEditingController.selection = TextSelection(
283 | baseOffset: textEditingController.selection.baseOffset + offSet,
284 | extentOffset:
285 | textEditingController.selection.extentOffset + offSet);
286 | if (tokenConfig.meta != null) {
287 | tokenConfig.meta.collection.add(SelectionInfo(
288 | indexAt, indexAt + addToInput.length - 1, suggestion.data));
289 | }
290 | setState(() {});
291 | });
292 | }).toList(),
293 | );
294 | }
295 |
296 | triggerSave() {
297 | if (widget.onSaved != null) {
298 | widget.onSaved(textEditingController.text);
299 | }
300 | }
301 |
302 | @override
303 | void dispose() {
304 | textEditingController.dispose();
305 | WidgetsBinding.instance.removeObserver(this);
306 | clearSuggestions();
307 | super.dispose();
308 | }
309 | }
310 |
311 | class MarkdownEditorController {
312 | _MarkdownEditorState __state;
313 | List listeners = [];
314 |
315 | set _state(_MarkdownEditorState state) {
316 | __state = state;
317 | updateListeners();
318 | }
319 |
320 | _MarkdownEditorState get _state => __state;
321 |
322 | TextEditingController get controller => _state?.textEditingController;
323 | String get text => _state?.textEditingController?.text;
324 |
325 | triggerSave() {
326 | _state?.triggerSave();
327 | }
328 |
329 | updateListeners() {
330 | if (controller == null) return;
331 | for (VoidCallback listener in listeners) {
332 | controller.addListener(listener);
333 | }
334 | listeners = [];
335 | }
336 |
337 | addListener(VoidCallback listener) {
338 | listeners.add(listener);
339 | updateListeners();
340 | }
341 | }
342 |
--------------------------------------------------------------------------------
/lib/mdviewer.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:adhara_markdown/mdbean.dart';
3 | import 'package:adhara_markdown/utils.dart';
4 |
5 | class MarkdownViewer extends StatelessWidget {
6 | final String content;
7 | final int loggedInUser;
8 | final TextStyle textStyle;
9 | final TextStyle highlightedTextStyle;
10 | final TextStyle fadedStyle;
11 | final List formatTypes;
12 | final bool collapsible;
13 | final List tokenConfigs;
14 | final int collapseLimit;
15 |
16 | MarkdownViewer(
17 | {Key key,
18 | this.content: "",
19 | this.loggedInUser,
20 | this.textStyle: const TextStyle(color: Colors.black),
21 | this.highlightedTextStyle: const TextStyle(color: Colors.indigo),
22 | this.formatTypes,
23 | this.collapsible: false,
24 | this.collapseLimit: 240,
25 | this.tokenConfigs,
26 | this.fadedStyle: const TextStyle(color: Colors.grey, fontSize: 12.0)})
27 | : super(key: key);
28 |
29 | get _textSpanConfigs =>
30 | tokenConfigs ??
31 | [
32 | MarkdownTokenConfig.mention(textStyle: highlightedTextStyle),
33 | MarkdownTokenConfig.link(textStyle: highlightedTextStyle),
34 | MarkdownTokenConfig.hashTag(textStyle: highlightedTextStyle),
35 | MarkdownTokenConfig.bold(textStyle: textStyle),
36 | MarkdownTokenConfig.italic(textStyle: textStyle),
37 | MarkdownTokenConfig.strikeThrough(textStyle: textStyle),
38 | MarkdownTokenConfig.code(textStyle: textStyle),
39 | ];
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | int len = 0;
44 | List richTextChildren = [];
45 | bool showReadMore = false;
46 | for (MarkdownToken span in _convertPostToTextSpans(context, content)) {
47 | if (!collapsible || len < collapseLimit) {
48 | richTextChildren.add(span.getSpan());
49 | } else {
50 | showReadMore = true;
51 | }
52 | len += span.text.length;
53 | }
54 | if (showReadMore) {
55 | richTextChildren.add(MarkdownToken(
56 | config: MarkdownTokenConfig(
57 | type: null, regExp: null, textStyle: textStyle),
58 | text: "...")
59 | .getSpan());
60 | richTextChildren.add(TextSpan(
61 | text: "Read more",
62 | style: fadedStyle.copyWith(
63 | color: fadedStyle.color.withOpacity(0.6),
64 | decoration: TextDecoration.underline,
65 | height: 1.3),
66 | recognizer: null,
67 | ));
68 | }
69 |
70 | return RichText(
71 | text: new TextSpan(
72 | children: richTextChildren,
73 | ),
74 | );
75 | }
76 |
77 | _convertPostToTextSpans(BuildContext context, String content) {
78 | List contentSpans = [content];
79 | for (MarkdownTokenConfig spanConfig in _textSpanConfigs) {
80 | if (formatTypes == null || formatTypes.indexOf(spanConfig.type) != -1) {
81 | if (spanConfig.meta != null) {
82 | contentSpans = splitUserTokens(contentSpans, spanConfig);
83 | } else {
84 | contentSpans = splitTokensByRegex(contentSpans, spanConfig);
85 | }
86 | }
87 | }
88 | return contentSpans.map((postSpan) {
89 | if (postSpan is String) {
90 | return MarkdownToken(
91 | config: MarkdownTokenConfig(
92 | type: null, regExp: null, textStyle: textStyle),
93 | text: postSpan);
94 | } else {
95 | return postSpan;
96 | }
97 | }).toList();
98 | }
99 |
100 | splitUserTokens(List strings, MarkdownTokenConfig userSpanConfig) {
101 | List returnTexts = [];
102 | for (var text in strings) {
103 | if (text is String) {
104 | int startIndex = 0;
105 | if (userSpanConfig.meta != null) {
106 | userSpanConfig.meta.collection.forEach((SelectionInfo info) {
107 | returnTexts.add(text.substring(startIndex, info.startIndex));
108 | returnTexts.add(
109 | MarkdownToken(
110 | config: userSpanConfig,
111 | selectionInfo: info,
112 | text: text.substring(info.startIndex, info.endIndex + 1),
113 | ),
114 | );
115 | startIndex = info.endIndex + 1;
116 | });
117 | }
118 | returnTexts.add(text.substring(startIndex, text.length));
119 | }
120 | }
121 | return returnTexts;
122 | }
123 |
124 | splitTokensByRegex(List strings, MarkdownTokenConfig spanConfig) {
125 | List returnTexts = [];
126 | for (var text in strings) {
127 | if (text is String) {
128 | Iterable matches = spanConfig.regExp.allMatches(text);
129 | int startIndex = 0;
130 | for (Match m in matches) {
131 | returnTexts.add(text.substring(startIndex, m.start));
132 | String matchedText = text.substring(m.start, m.end);
133 | returnTexts.add(MarkdownToken(
134 | config: spanConfig,
135 | text: (spanConfig.postProcess != null)
136 | ? spanConfig.postProcess(matchedText)
137 | : matchedText,
138 | ));
139 | startIndex = m.end;
140 | }
141 | returnTexts.add(text.substring(startIndex, text.length));
142 | } else {
143 | returnTexts.add(text);
144 | }
145 | }
146 | return returnTexts;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/lib/utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:url_launcher/url_launcher.dart';
2 | import 'package:flutter/gestures.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:adhara_markdown/mdbean.dart';
5 |
6 | typedef String StringCallbackFn(String span);
7 | typedef void AdharaRichTextSpanTapCallback(MarkdownToken richTextSpan);
8 | typedef Future> AdharaRichTextSuggestionCallback(
9 | String hint);
10 | typedef String OnSuggestionInsert();
11 | typedef void OnSavedCallback(String content);
12 |
13 | enum MarkdownTokenTypes {
14 | link,
15 | mention,
16 | hashTag,
17 | bold,
18 | italic,
19 | strikeThrough,
20 | code
21 | }
22 |
23 | void urlOpener(MarkdownToken span) async {
24 | if (await canLaunch(span.text)) {
25 | await launch(span.text);
26 | } else {
27 | throw 'Could not launch ${span.text}';
28 | }
29 | }
30 |
31 | String stripFirstAndLast(String text) => text.substring(1, text.length - 1);
32 |
33 | String _baseCharacters = r'a-zA-Z0-9\/?.",!:<>' + r"'";
34 |
35 | class MarkdownTokenConfig {
36 | final MarkdownTokenTypes type;
37 | final RegExp regExp;
38 | final RegExp hintRegExp;
39 | final TextStyle textStyle;
40 | final StringCallbackFn postProcess;
41 | final MarkdownMeta meta;
42 | final AdharaRichTextSpanTapCallback onTap;
43 | final AdharaRichTextSuggestionCallback suggestions;
44 |
45 | MarkdownTokenConfig(
46 | {@required this.type,
47 | @required this.textStyle,
48 | this.regExp,
49 | this.hintRegExp,
50 | this.postProcess,
51 | this.meta,
52 | this.onTap,
53 | this.suggestions});
54 |
55 | MarkdownTokenConfig.mention(
56 | {this.textStyle,
57 | this.postProcess,
58 | this.meta,
59 | this.onTap,
60 | this.suggestions})
61 | : type = MarkdownTokenTypes.mention,
62 | regExp = RegExp(r'@[0-9a-zA-Z.\s]+'),
63 | hintRegExp = RegExp(r"@[0-9a-zA-Z.\s]*");
64 |
65 | MarkdownTokenConfig.link({this.textStyle, this.postProcess})
66 | : type = MarkdownTokenTypes.link,
67 | regExp = RegExp(r'((http[s]{0,1}:\/\/)[a-zA-Z0-9\.%\/?:&,\-_#="]*)'),
68 | hintRegExp = null,
69 | meta = null,
70 | suggestions = null,
71 | onTap = urlOpener;
72 |
73 | MarkdownTokenConfig.hashTag(
74 | {this.textStyle, this.suggestions, this.postProcess, this.onTap})
75 | : type = MarkdownTokenTypes.hashTag,
76 | regExp = RegExp(r'#[' + _baseCharacters + ']+'),
77 | hintRegExp = RegExp(r'#[' + _baseCharacters + '\-]*'),
78 | meta = null;
79 |
80 | MarkdownTokenConfig.bold({TextStyle textStyle, StringCallbackFn postProcess})
81 | : type = MarkdownTokenTypes.bold,
82 | regExp = RegExp(r'\*[' + _baseCharacters + r'_~`\-\s]*\*'),
83 | hintRegExp = null,
84 | textStyle = textStyle.copyWith(fontWeight: FontWeight.bold),
85 | postProcess = postProcess ?? stripFirstAndLast,
86 | meta = null,
87 | suggestions = null,
88 | onTap = null;
89 |
90 | MarkdownTokenConfig.italic(
91 | {TextStyle textStyle, StringCallbackFn postProcess})
92 | : type = MarkdownTokenTypes.italic,
93 | regExp = RegExp(r'_[' + _baseCharacters + r'~`\-\*\s]*_'),
94 | hintRegExp = null,
95 | textStyle = textStyle.copyWith(fontStyle: FontStyle.italic),
96 | postProcess = postProcess ?? stripFirstAndLast,
97 | meta = null,
98 | suggestions = null,
99 | onTap = null;
100 |
101 | MarkdownTokenConfig.strikeThrough(
102 | {TextStyle textStyle, StringCallbackFn postProcess})
103 | : type = MarkdownTokenTypes.strikeThrough,
104 | regExp = RegExp(r'~[' + _baseCharacters + r'_`\-\*\s]*~'),
105 | hintRegExp = null,
106 | textStyle = textStyle.copyWith(decoration: TextDecoration.lineThrough),
107 | postProcess = postProcess ?? stripFirstAndLast,
108 | meta = null,
109 | suggestions = null,
110 | onTap = null;
111 |
112 | MarkdownTokenConfig.code({TextStyle textStyle, StringCallbackFn postProcess})
113 | : type = MarkdownTokenTypes.code,
114 | regExp = RegExp(r'`[' + _baseCharacters + r'~_\-\*\s]*`'),
115 | hintRegExp = null,
116 | textStyle = textStyle.copyWith(fontFamily: "Monospace"),
117 | postProcess = postProcess ?? stripFirstAndLast,
118 | meta = null,
119 | suggestions = null,
120 | onTap = null;
121 | }
122 |
123 | class MarkdownToken {
124 | final MarkdownTokenConfig config;
125 | final SelectionInfo selectionInfo;
126 | final String text;
127 |
128 | MarkdownToken(
129 | {@required this.text, @required this.config, this.selectionInfo});
130 |
131 | TextSpan getSpan() {
132 | return TextSpan(
133 | text: text,
134 | style: config.textStyle,
135 | recognizer: (this.config.onTap != null)
136 | ? (TapGestureRecognizer()
137 | ..onTap = () {
138 | this.config.onTap(this);
139 | })
140 | : null,
141 | );
142 | }
143 | }
144 |
145 | class TokenSuggestion {
146 | Widget display;
147 | dynamic data;
148 | OnSuggestionInsert onInsert;
149 |
150 | TokenSuggestion({this.display, this.data, this.onInsert});
151 | }
152 |
--------------------------------------------------------------------------------
/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.5.0"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "2.1.0"
18 | characters:
19 | dependency: transitive
20 | description:
21 | name: characters
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "1.1.0"
25 | charcode:
26 | dependency: transitive
27 | description:
28 | name: charcode
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.2.0"
32 | clock:
33 | dependency: transitive
34 | description:
35 | name: clock
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "1.1.0"
39 | collection:
40 | dependency: transitive
41 | description:
42 | name: collection
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.15.0"
46 | fake_async:
47 | dependency: transitive
48 | description:
49 | name: fake_async
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "1.2.0"
53 | flutter:
54 | dependency: "direct main"
55 | description: flutter
56 | source: sdk
57 | version: "0.0.0"
58 | flutter_test:
59 | dependency: "direct dev"
60 | description: flutter
61 | source: sdk
62 | version: "0.0.0"
63 | flutter_web_plugins:
64 | dependency: transitive
65 | description: flutter
66 | source: sdk
67 | version: "0.0.0"
68 | js:
69 | dependency: transitive
70 | description:
71 | name: js
72 | url: "https://pub.dartlang.org"
73 | source: hosted
74 | version: "0.6.3"
75 | matcher:
76 | dependency: transitive
77 | description:
78 | name: matcher
79 | url: "https://pub.dartlang.org"
80 | source: hosted
81 | version: "0.12.10"
82 | meta:
83 | dependency: transitive
84 | description:
85 | name: meta
86 | url: "https://pub.dartlang.org"
87 | source: hosted
88 | version: "1.3.0"
89 | path:
90 | dependency: transitive
91 | description:
92 | name: path
93 | url: "https://pub.dartlang.org"
94 | source: hosted
95 | version: "1.8.0"
96 | plugin_platform_interface:
97 | dependency: transitive
98 | description:
99 | name: plugin_platform_interface
100 | url: "https://pub.dartlang.org"
101 | source: hosted
102 | version: "2.0.0"
103 | sky_engine:
104 | dependency: transitive
105 | description: flutter
106 | source: sdk
107 | version: "0.0.99"
108 | source_span:
109 | dependency: transitive
110 | description:
111 | name: source_span
112 | url: "https://pub.dartlang.org"
113 | source: hosted
114 | version: "1.8.0"
115 | stack_trace:
116 | dependency: transitive
117 | description:
118 | name: stack_trace
119 | url: "https://pub.dartlang.org"
120 | source: hosted
121 | version: "1.10.0"
122 | stream_channel:
123 | dependency: transitive
124 | description:
125 | name: stream_channel
126 | url: "https://pub.dartlang.org"
127 | source: hosted
128 | version: "2.1.0"
129 | string_scanner:
130 | dependency: transitive
131 | description:
132 | name: string_scanner
133 | url: "https://pub.dartlang.org"
134 | source: hosted
135 | version: "1.1.0"
136 | term_glyph:
137 | dependency: transitive
138 | description:
139 | name: term_glyph
140 | url: "https://pub.dartlang.org"
141 | source: hosted
142 | version: "1.2.0"
143 | test_api:
144 | dependency: transitive
145 | description:
146 | name: test_api
147 | url: "https://pub.dartlang.org"
148 | source: hosted
149 | version: "0.2.19"
150 | typed_data:
151 | dependency: transitive
152 | description:
153 | name: typed_data
154 | url: "https://pub.dartlang.org"
155 | source: hosted
156 | version: "1.3.0"
157 | url_launcher:
158 | dependency: "direct main"
159 | description:
160 | name: url_launcher
161 | url: "https://pub.dartlang.org"
162 | source: hosted
163 | version: "6.0.3"
164 | url_launcher_linux:
165 | dependency: transitive
166 | description:
167 | name: url_launcher_linux
168 | url: "https://pub.dartlang.org"
169 | source: hosted
170 | version: "2.0.0"
171 | url_launcher_macos:
172 | dependency: transitive
173 | description:
174 | name: url_launcher_macos
175 | url: "https://pub.dartlang.org"
176 | source: hosted
177 | version: "2.0.0"
178 | url_launcher_platform_interface:
179 | dependency: transitive
180 | description:
181 | name: url_launcher_platform_interface
182 | url: "https://pub.dartlang.org"
183 | source: hosted
184 | version: "2.0.2"
185 | url_launcher_web:
186 | dependency: transitive
187 | description:
188 | name: url_launcher_web
189 | url: "https://pub.dartlang.org"
190 | source: hosted
191 | version: "2.0.0"
192 | url_launcher_windows:
193 | dependency: transitive
194 | description:
195 | name: url_launcher_windows
196 | url: "https://pub.dartlang.org"
197 | source: hosted
198 | version: "2.0.0"
199 | vector_math:
200 | dependency: transitive
201 | description:
202 | name: vector_math
203 | url: "https://pub.dartlang.org"
204 | source: hosted
205 | version: "2.1.0"
206 | sdks:
207 | dart: ">=2.12.0-259.9.beta <3.0.0"
208 | flutter: ">=1.22.0"
209 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: adhara_markdown
2 | description: Minimalistic, highly customizable, regexp based markdown editor and viewer by adhara
3 | version: 0.2.0
4 | homepage: https://github.com/infitio/flutter_markdown
5 |
6 | environment:
7 | sdk: ">=2.2.0 <3.0.0"
8 |
9 | dependencies:
10 | flutter:
11 | sdk: flutter
12 | url_launcher: ^6.0.2
13 |
14 | dev_dependencies:
15 | flutter_test:
16 | sdk: flutter
17 |
18 | # For information on the generic Dart part of this file, see the
19 | # following page: https://www.dartlang.org/tools/pub/pubspec
20 |
21 | # The following section is specific to Flutter.
22 | flutter:
23 |
24 | # To add assets to your package, add an assets section, like this:
25 | # assets:
26 | # - images/a_dot_burr.jpeg
27 | # - images/a_dot_ham.jpeg
28 | #
29 | # For details regarding assets in packages, see
30 | # https://flutter.io/assets-and-images/#from-packages
31 | #
32 | # An image asset can refer to one or more resolution-specific "variants", see
33 | # https://flutter.io/assets-and-images/#resolution-aware.
34 |
35 | # To add custom fonts to your package, add a fonts section here,
36 | # in this "flutter" section. Each entry in this list should have a
37 | # "family" key with the font family name, and a "fonts" key with a
38 | # list giving the asset and other descriptors for the font. For
39 | # example:
40 | # fonts:
41 | # - family: Schyler
42 | # fonts:
43 | # - asset: fonts/Schyler-Regular.ttf
44 | # - asset: fonts/Schyler-Italic.ttf
45 | # style: italic
46 | # - family: Trajan Pro
47 | # fonts:
48 | # - asset: fonts/TrajanPro.ttf
49 | # - asset: fonts/TrajanPro_Bold.ttf
50 | # weight: 700
51 | #
52 | # For details regarding fonts in packages, see
53 | # https://flutter.io/custom-fonts/#from-packages
54 |
--------------------------------------------------------------------------------
/test/adhara_markdown_test.dart:
--------------------------------------------------------------------------------
1 | /*
2 | import 'package:flutter_test/flutter_test.dart';
3 |
4 | import 'package:adhara_markdown/adhara_markdown.dart';
5 |
6 | void main() {
7 | test('adds one to input values', () {
8 | */
9 | /*final calculator = Calculator();
10 | expect(calculator.addOne(2), 3);
11 | expect(calculator.addOne(-7), -6);
12 | expect(calculator.addOne(0), 1);
13 | expect(() => calculator.addOne(null), throwsNoSuchMethodError);*/ /*
14 |
15 | });
16 | }
17 | */
18 |
--------------------------------------------------------------------------------