박유빈

add README

Showing 109 changed files with 5008 additions and 0 deletions
1 +# Miscellaneous
2 +*.class
3 +*.log
4 +*.pyc
5 +*.swp
6 +.DS_Store
7 +.atom/
8 +.buildlog/
9 +.history
10 +.svn/
11 +
12 +# IntelliJ related
13 +*.iml
14 +*.ipr
15 +*.iws
16 +.idea/
17 +
18 +# The .vscode folder contains launch configuration and tasks you configure in
19 +# VS Code which you may wish to be included in version control, so this line
20 +# is commented out by default.
21 +#.vscode/
22 +
23 +# Flutter/Dart/Pub related
24 +**/doc/api/
25 +**/ios/Flutter/.last_build_id
26 +.dart_tool/
27 +.flutter-plugins
28 +.flutter-plugins-dependencies
29 +.packages
30 +.pub-cache/
31 +.pub/
32 +/build/
33 +
34 +# Web related
35 +lib/generated_plugin_registrant.dart
36 +
37 +# Symbolication related
38 +app.*.symbols
39 +
40 +# Obfuscation related
41 +app.*.map.json
42 +
43 +# Android Studio will place build artifacts here
44 +/android/app/debug
45 +/android/app/profile
46 +/android/app/release
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: 18116933e77adc82f80866c928266a5b4f1ed645
8 + channel: stable
9 +
10 +project_type: app
1 +<!-- ABOUT THE PROJECT -->
2 +## About The Project
3 +이 프로젝트는 누군가의 창작물을 언어장벽 없이 감상하고 공유하고자 하는 웹서비스 입니다.
4 +우리는 도구로 언어를 사용하고 있습니다. 때로는 그것이 다른 사람과 달라 정보, 마음 등이 전달되지 않을 때가 많습니다.
5 +세계 장벽이 허물어지고 인터넷으로 소통이 가능한 사람들이 가끔은 다른 언어 때문에 다양한 생각과 정보를 얻기 어렵습니다.
6 +이 프로젝트는 이 어려움을 깨고자 시작했습니다.
7 +누군가의 글을 보고 영감을 얻어 여러 언어로 바꿔나가고 공유하며 다양한 시각을 가질 수 있습니다.
8 +
9 +<p align="right">(<a href="#top">back to top</a>)</p>
10 +
11 +## Getting Started
12 +
13 +This project is a starting point for a Flutter application.
14 +
15 +A few resources to get you started if this is your first Flutter project:
16 +
17 +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
18 +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
19 +
20 +For help getting started with Flutter, view our
21 +[online documentation](https://flutter.dev/docs), which offers tutorials,
22 +samples, guidance on mobile development, and a full API reference.
23 +
24 +
25 +
26 +### Built With
27 +
28 +server use Node.js, Koa.js and frotend use flutter(Dart)
29 +
30 +* [Node.js](https://nodejs.org/)
31 +* [Koa.js](https://koajs.com/)
32 +
33 +* [flutter](https://flutter.dev/)
34 +
35 +
36 +
37 +<p align="right">(<a href="#top">back to top</a>)</p>
38 +
39 +
40 +
41 +<!-- GETTING STARTED -->
42 +## Getting Started
43 +
44 +Go to the Server [Project folder](http://khuhub.khu.ac.kr/2018102946/likeBack), and git clone.
45 +And go the Frontend [Project folder](http://khuhub.khu.ac.kr/2018102946/likefront)and git clone.
46 +
47 +
48 +### Installation
49 +
50 +(flutter web) [https://docs.flutter.dev/get-started/web]
51 +Requirements
52 +To create a Flutter app with web support, you need the following software:
53 +
54 +Flutter SDK. See the [Flutter SDK](https://docs.flutter.dev/get-started/install) installation instructions.
55 +[Chrome](https://www.google.com/chrome/); debugging a web app requires the Chrome browser.
56 +Optional: An IDE that supports Flutter. You can install [Android Studio](https://developer.android.com/studio), IntelliJ IDEA, or Visual Studio Code and [install the Flutter and Dart plugins](https://docs.flutter.dev/get-started/editor) to enable language support and tools for refactoring, running, debugging, and reloading your web app within an editor. See setting up an editor for more details.
57 +For more information, see the web FAQ.
58 +
59 +
60 +1. Clone the repo
61 + ```sh
62 + git clone http://khuhub.khu.ac.kr/2018102946/likefront.git
63 + ```
64 +2. Install NPM packages
65 + ```sh
66 + cd like
67 + ```
68 +3. Run with chorme
69 + ```sh
70 + flutter run -d chrome
71 + ```
72 +*Build web
73 + ```sh
74 + flutter build web
75 + ```
76 +<p align="right">(<a href="#top">back to top</a>)</p>
...\ No newline at end of file ...\ No newline at end of file
1 +# This file configures the analyzer, which statically analyzes Dart code to
2 +# check for errors, warnings, and lints.
3 +#
4 +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 +# invoked from the command line by running `flutter analyze`.
7 +
8 +# The following line activates a set of recommended lints for Flutter apps,
9 +# packages, and plugins designed to encourage good coding practices.
10 +include: package:flutter_lints/flutter.yaml
11 +
12 +linter:
13 + # The lint rules applied to this project can be customized in the
14 + # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 + # included above or to enable additional rules. A list of all available lints
16 + # and their documentation is published at
17 + # https://dart-lang.github.io/linter/lints/index.html.
18 + #
19 + # Instead of disabling a lint rule for the entire project in the
20 + # section below, it can also be suppressed for a single line of code
21 + # or a specific dart file by using the `// ignore: name_of_lint` and
22 + # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 + # producing the lint.
24 + rules:
25 + # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 +
28 +# Additional information about this file can be found at
29 +# https://dart.dev/guides/language/analysis-options
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 +**/*.keystore
13 +**/*.jks
1 +def localProperties = new Properties()
2 +def localPropertiesFile = rootProject.file('local.properties')
3 +if (localPropertiesFile.exists()) {
4 + localPropertiesFile.withReader('UTF-8') { reader ->
5 + localProperties.load(reader)
6 + }
7 +}
8 +
9 +def flutterRoot = localProperties.getProperty('flutter.sdk')
10 +if (flutterRoot == null) {
11 + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 +}
13 +
14 +def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 +if (flutterVersionCode == null) {
16 + flutterVersionCode = '1'
17 +}
18 +
19 +def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 +if (flutterVersionName == null) {
21 + flutterVersionName = '1.0'
22 +}
23 +
24 +apply plugin: 'com.android.application'
25 +apply plugin: 'kotlin-android'
26 +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 +
28 +android {
29 + compileSdkVersion 30
30 +
31 + compileOptions {
32 + sourceCompatibility JavaVersion.VERSION_1_8
33 + targetCompatibility JavaVersion.VERSION_1_8
34 + }
35 +
36 + kotlinOptions {
37 + jvmTarget = '1.8'
38 + }
39 +
40 + sourceSets {
41 + main.java.srcDirs += 'src/main/kotlin'
42 + }
43 +
44 + defaultConfig {
45 + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
46 + applicationId "com.example.like"
47 + minSdkVersion 16
48 + targetSdkVersion 30
49 + versionCode flutterVersionCode.toInteger()
50 + versionName flutterVersionName
51 + }
52 +
53 + buildTypes {
54 + release {
55 + // TODO: Add your own signing config for the release build.
56 + // Signing with the debug keys for now, so `flutter run --release` works.
57 + signingConfig signingConfigs.debug
58 + }
59 + }
60 +}
61 +
62 +flutter {
63 + source '../..'
64 +}
65 +
66 +dependencies {
67 + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
68 +}
1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 + package="com.example.like">
3 + <!-- Flutter needs it to communicate with the running application
4 + to allow setting breakpoints, to provide hot reload, etc.
5 + -->
6 + <uses-permission android:name="android.permission.INTERNET"/>
7 +</manifest>
1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 + package="com.example.like">
3 + <application
4 + android:label="like"
5 + android:icon="@mipmap/ic_launcher">
6 + <activity
7 + android:name=".MainActivity"
8 + android:launchMode="singleTop"
9 + android:theme="@style/LaunchTheme"
10 + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
11 + android:hardwareAccelerated="true"
12 + android:windowSoftInputMode="adjustResize">
13 + <!-- Specifies an Android theme to apply to this Activity as soon as
14 + the Android process has started. This theme is visible to the user
15 + while the Flutter UI initializes. After that, this theme continues
16 + to determine the Window background behind the Flutter UI. -->
17 + <meta-data
18 + android:name="io.flutter.embedding.android.NormalTheme"
19 + android:resource="@style/NormalTheme"
20 + />
21 + <!-- Displays an Android View that continues showing the launch screen
22 + Drawable until Flutter paints its first frame, then this splash
23 + screen fades out. A splash screen is useful to avoid any visual
24 + gap between the end of Android's launch screen and the painting of
25 + Flutter's first frame. -->
26 + <meta-data
27 + android:name="io.flutter.embedding.android.SplashScreenDrawable"
28 + android:resource="@drawable/launch_background"
29 + />
30 + <intent-filter>
31 + <action android:name="android.intent.action.MAIN"/>
32 + <category android:name="android.intent.category.LAUNCHER"/>
33 + </intent-filter>
34 + </activity>
35 + <!-- Don't delete the meta-data below.
36 + This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
37 + <meta-data
38 + android:name="flutterEmbedding"
39 + android:value="2" />
40 + </application>
41 +</manifest>
1 +package com.example.like
2 +
3 +import io.flutter.embedding.android.FlutterActivity
4 +
5 +class MainActivity: FlutterActivity() {
6 +}
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- Modify this file to customize your launch splash screen -->
3 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4 + <item android:drawable="?android:colorBackground" />
5 +
6 + <!-- You can insert your own image assets here -->
7 + <!-- <item>
8 + <bitmap
9 + android:gravity="center"
10 + android:src="@mipmap/launch_image" />
11 + </item> -->
12 +</layer-list>
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<!-- Modify this file to customize your launch splash screen -->
3 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4 + <item android:drawable="@android:color/white" />
5 +
6 + <!-- You can insert your own image assets here -->
7 + <!-- <item>
8 + <bitmap
9 + android:gravity="center"
10 + android:src="@mipmap/launch_image" />
11 + </item> -->
12 +</layer-list>
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<resources>
3 + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
4 + <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
5 + <!-- Show a splash screen on the activity. Automatically removed when
6 + Flutter draws its first frame -->
7 + <item name="android:windowBackground">@drawable/launch_background</item>
8 + </style>
9 + <!-- Theme applied to the Android Window as soon as the process has started.
10 + This theme determines the color of the Android Window while your
11 + Flutter UI initializes, as well as behind your Flutter UI while its
12 + running.
13 +
14 + This Theme is only used starting with V2 of Flutter's Android embedding. -->
15 + <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
16 + <item name="android:windowBackground">?android:colorBackground</item>
17 + </style>
18 +</resources>
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<resources>
3 + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
4 + <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
5 + <!-- Show a splash screen on the activity. Automatically removed when
6 + Flutter draws its first frame -->
7 + <item name="android:windowBackground">@drawable/launch_background</item>
8 + </style>
9 + <!-- Theme applied to the Android Window as soon as the process has started.
10 + This theme determines the color of the Android Window while your
11 + Flutter UI initializes, as well as behind your Flutter UI while its
12 + running.
13 +
14 + This Theme is only used starting with V2 of Flutter's Android embedding. -->
15 + <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
16 + <item name="android:windowBackground">?android:colorBackground</item>
17 + </style>
18 +</resources>
1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 + package="com.example.like">
3 + <!-- Flutter needs it to communicate with the running application
4 + to allow setting breakpoints, to provide hot reload, etc.
5 + -->
6 + <uses-permission android:name="android.permission.INTERNET"/>
7 +</manifest>
1 +buildscript {
2 + ext.kotlin_version = '1.3.50'
3 + repositories {
4 + google()
5 + mavenCentral()
6 + }
7 +
8 + dependencies {
9 + classpath 'com.android.tools.build:gradle:4.1.0'
10 + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 + }
12 +}
13 +
14 +allprojects {
15 + repositories {
16 + google()
17 + mavenCentral()
18 + }
19 +}
20 +
21 +rootProject.buildDir = '../build'
22 +subprojects {
23 + project.buildDir = "${rootProject.buildDir}/${project.name}"
24 + project.evaluationDependsOn(':app')
25 +}
26 +
27 +task clean(type: Delete) {
28 + delete rootProject.buildDir
29 +}
1 +org.gradle.jvmargs=-Xmx1536M
2 +android.useAndroidX=true
3 +android.enableJetifier=true
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.7-all.zip
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"
No preview for this file type
No preview for this file type
1 +**/dgph
2 +*.mode1v3
3 +*.mode2v3
4 +*.moved-aside
5 +*.pbxuser
6 +*.perspectivev3
7 +**/*sync/
8 +.sconsign.dblite
9 +.tags*
10 +**/.vagrant/
11 +**/DerivedData/
12 +Icon?
13 +**/Pods/
14 +**/.symlinks/
15 +profile
16 +xcuserdata
17 +**/.generated/
18 +Flutter/App.framework
19 +Flutter/Flutter.framework
20 +Flutter/Flutter.podspec
21 +Flutter/Generated.xcconfig
22 +Flutter/ephemeral/
23 +Flutter/app.flx
24 +Flutter/app.zip
25 +Flutter/flutter_assets/
26 +Flutter/flutter_export_environment.sh
27 +ServiceDefinitions.json
28 +Runner/GeneratedPluginRegistrant.*
29 +
30 +# Exceptions to above rules.
31 +!default.mode1v3
32 +!default.mode2v3
33 +!default.pbxuser
34 +!default.perspectivev3
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 +<plist version="1.0">
4 +<dict>
5 + <key>CFBundleDevelopmentRegion</key>
6 + <string>en</string>
7 + <key>CFBundleExecutable</key>
8 + <string>App</string>
9 + <key>CFBundleIdentifier</key>
10 + <string>io.flutter.flutter.app</string>
11 + <key>CFBundleInfoDictionaryVersion</key>
12 + <string>6.0</string>
13 + <key>CFBundleName</key>
14 + <string>App</string>
15 + <key>CFBundlePackageType</key>
16 + <string>FMWK</string>
17 + <key>CFBundleShortVersionString</key>
18 + <string>1.0</string>
19 + <key>CFBundleSignature</key>
20 + <string>????</string>
21 + <key>CFBundleVersion</key>
22 + <string>1.0</string>
23 + <key>MinimumOSVersion</key>
24 + <string>9.0</string>
25 +</dict>
26 +</plist>
1 +#include "Generated.xcconfig"
1 +#include "Generated.xcconfig"
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 + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
13 + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
14 + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
15 + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
16 +/* End PBXBuildFile section */
17 +
18 +/* Begin PBXCopyFilesBuildPhase section */
19 + 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
20 + isa = PBXCopyFilesBuildPhase;
21 + buildActionMask = 2147483647;
22 + dstPath = "";
23 + dstSubfolderSpec = 10;
24 + files = (
25 + );
26 + name = "Embed Frameworks";
27 + runOnlyForDeploymentPostprocessing = 0;
28 + };
29 +/* End PBXCopyFilesBuildPhase section */
30 +
31 +/* Begin PBXFileReference section */
32 + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
33 + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
34 + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
35 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
36 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
37 + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
38 + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
39 + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
40 + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
41 + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
42 + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
43 + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
44 + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
45 +/* End PBXFileReference section */
46 +
47 +/* Begin PBXFrameworksBuildPhase section */
48 + 97C146EB1CF9000F007C117D /* Frameworks */ = {
49 + isa = PBXFrameworksBuildPhase;
50 + buildActionMask = 2147483647;
51 + files = (
52 + );
53 + runOnlyForDeploymentPostprocessing = 0;
54 + };
55 +/* End PBXFrameworksBuildPhase section */
56 +
57 +/* Begin PBXGroup section */
58 + 9740EEB11CF90186004384FC /* Flutter */ = {
59 + isa = PBXGroup;
60 + children = (
61 + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
62 + 9740EEB21CF90195004384FC /* Debug.xcconfig */,
63 + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
64 + 9740EEB31CF90195004384FC /* Generated.xcconfig */,
65 + );
66 + name = Flutter;
67 + sourceTree = "<group>";
68 + };
69 + 97C146E51CF9000F007C117D = {
70 + isa = PBXGroup;
71 + children = (
72 + 9740EEB11CF90186004384FC /* Flutter */,
73 + 97C146F01CF9000F007C117D /* Runner */,
74 + 97C146EF1CF9000F007C117D /* Products */,
75 + );
76 + sourceTree = "<group>";
77 + };
78 + 97C146EF1CF9000F007C117D /* Products */ = {
79 + isa = PBXGroup;
80 + children = (
81 + 97C146EE1CF9000F007C117D /* Runner.app */,
82 + );
83 + name = Products;
84 + sourceTree = "<group>";
85 + };
86 + 97C146F01CF9000F007C117D /* Runner */ = {
87 + isa = PBXGroup;
88 + children = (
89 + 97C146FA1CF9000F007C117D /* Main.storyboard */,
90 + 97C146FD1CF9000F007C117D /* Assets.xcassets */,
91 + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
92 + 97C147021CF9000F007C117D /* Info.plist */,
93 + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
94 + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
95 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
96 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
97 + );
98 + path = Runner;
99 + sourceTree = "<group>";
100 + };
101 +/* End PBXGroup section */
102 +
103 +/* Begin PBXNativeTarget section */
104 + 97C146ED1CF9000F007C117D /* Runner */ = {
105 + isa = PBXNativeTarget;
106 + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
107 + buildPhases = (
108 + 9740EEB61CF901F6004384FC /* Run Script */,
109 + 97C146EA1CF9000F007C117D /* Sources */,
110 + 97C146EB1CF9000F007C117D /* Frameworks */,
111 + 97C146EC1CF9000F007C117D /* Resources */,
112 + 9705A1C41CF9048500538489 /* Embed Frameworks */,
113 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
114 + );
115 + buildRules = (
116 + );
117 + dependencies = (
118 + );
119 + name = Runner;
120 + productName = Runner;
121 + productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
122 + productType = "com.apple.product-type.application";
123 + };
124 +/* End PBXNativeTarget section */
125 +
126 +/* Begin PBXProject section */
127 + 97C146E61CF9000F007C117D /* Project object */ = {
128 + isa = PBXProject;
129 + attributes = {
130 + LastUpgradeCheck = 1020;
131 + ORGANIZATIONNAME = "";
132 + TargetAttributes = {
133 + 97C146ED1CF9000F007C117D = {
134 + CreatedOnToolsVersion = 7.3.1;
135 + LastSwiftMigration = 1100;
136 + };
137 + };
138 + };
139 + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
140 + compatibilityVersion = "Xcode 9.3";
141 + developmentRegion = en;
142 + hasScannedForEncodings = 0;
143 + knownRegions = (
144 + en,
145 + Base,
146 + );
147 + mainGroup = 97C146E51CF9000F007C117D;
148 + productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
149 + projectDirPath = "";
150 + projectRoot = "";
151 + targets = (
152 + 97C146ED1CF9000F007C117D /* Runner */,
153 + );
154 + };
155 +/* End PBXProject section */
156 +
157 +/* Begin PBXResourcesBuildPhase section */
158 + 97C146EC1CF9000F007C117D /* Resources */ = {
159 + isa = PBXResourcesBuildPhase;
160 + buildActionMask = 2147483647;
161 + files = (
162 + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
163 + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
164 + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
165 + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
166 + );
167 + runOnlyForDeploymentPostprocessing = 0;
168 + };
169 +/* End PBXResourcesBuildPhase section */
170 +
171 +/* Begin PBXShellScriptBuildPhase section */
172 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
173 + isa = PBXShellScriptBuildPhase;
174 + buildActionMask = 2147483647;
175 + files = (
176 + );
177 + inputPaths = (
178 + );
179 + name = "Thin Binary";
180 + outputPaths = (
181 + );
182 + runOnlyForDeploymentPostprocessing = 0;
183 + shellPath = /bin/sh;
184 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
185 + };
186 + 9740EEB61CF901F6004384FC /* Run Script */ = {
187 + isa = PBXShellScriptBuildPhase;
188 + buildActionMask = 2147483647;
189 + files = (
190 + );
191 + inputPaths = (
192 + );
193 + name = "Run Script";
194 + outputPaths = (
195 + );
196 + runOnlyForDeploymentPostprocessing = 0;
197 + shellPath = /bin/sh;
198 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
199 + };
200 +/* End PBXShellScriptBuildPhase section */
201 +
202 +/* Begin PBXSourcesBuildPhase section */
203 + 97C146EA1CF9000F007C117D /* Sources */ = {
204 + isa = PBXSourcesBuildPhase;
205 + buildActionMask = 2147483647;
206 + files = (
207 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
208 + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
209 + );
210 + runOnlyForDeploymentPostprocessing = 0;
211 + };
212 +/* End PBXSourcesBuildPhase section */
213 +
214 +/* Begin PBXVariantGroup section */
215 + 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
216 + isa = PBXVariantGroup;
217 + children = (
218 + 97C146FB1CF9000F007C117D /* Base */,
219 + );
220 + name = Main.storyboard;
221 + sourceTree = "<group>";
222 + };
223 + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
224 + isa = PBXVariantGroup;
225 + children = (
226 + 97C147001CF9000F007C117D /* Base */,
227 + );
228 + name = LaunchScreen.storyboard;
229 + sourceTree = "<group>";
230 + };
231 +/* End PBXVariantGroup section */
232 +
233 +/* Begin XCBuildConfiguration section */
234 + 249021D3217E4FDB00AE95B9 /* Profile */ = {
235 + isa = XCBuildConfiguration;
236 + buildSettings = {
237 + ALWAYS_SEARCH_USER_PATHS = NO;
238 + CLANG_ANALYZER_NONNULL = YES;
239 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
240 + CLANG_CXX_LIBRARY = "libc++";
241 + CLANG_ENABLE_MODULES = YES;
242 + CLANG_ENABLE_OBJC_ARC = YES;
243 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
244 + CLANG_WARN_BOOL_CONVERSION = YES;
245 + CLANG_WARN_COMMA = YES;
246 + CLANG_WARN_CONSTANT_CONVERSION = YES;
247 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
248 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
249 + CLANG_WARN_EMPTY_BODY = YES;
250 + CLANG_WARN_ENUM_CONVERSION = YES;
251 + CLANG_WARN_INFINITE_RECURSION = YES;
252 + CLANG_WARN_INT_CONVERSION = YES;
253 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
254 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
255 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
256 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
258 + CLANG_WARN_STRICT_PROTOTYPES = YES;
259 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
260 + CLANG_WARN_UNREACHABLE_CODE = YES;
261 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
262 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
263 + COPY_PHASE_STRIP = NO;
264 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
265 + ENABLE_NS_ASSERTIONS = NO;
266 + ENABLE_STRICT_OBJC_MSGSEND = YES;
267 + GCC_C_LANGUAGE_STANDARD = gnu99;
268 + GCC_NO_COMMON_BLOCKS = YES;
269 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
270 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
271 + GCC_WARN_UNDECLARED_SELECTOR = YES;
272 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
273 + GCC_WARN_UNUSED_FUNCTION = YES;
274 + GCC_WARN_UNUSED_VARIABLE = YES;
275 + IPHONEOS_DEPLOYMENT_TARGET = 9.0;
276 + MTL_ENABLE_DEBUG_INFO = NO;
277 + SDKROOT = iphoneos;
278 + SUPPORTED_PLATFORMS = iphoneos;
279 + TARGETED_DEVICE_FAMILY = "1,2";
280 + VALIDATE_PRODUCT = YES;
281 + };
282 + name = Profile;
283 + };
284 + 249021D4217E4FDB00AE95B9 /* Profile */ = {
285 + isa = XCBuildConfiguration;
286 + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
287 + buildSettings = {
288 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
289 + CLANG_ENABLE_MODULES = YES;
290 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
291 + ENABLE_BITCODE = NO;
292 + INFOPLIST_FILE = Runner/Info.plist;
293 + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
294 + PRODUCT_BUNDLE_IDENTIFIER = com.example.like;
295 + PRODUCT_NAME = "$(TARGET_NAME)";
296 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
297 + SWIFT_VERSION = 5.0;
298 + VERSIONING_SYSTEM = "apple-generic";
299 + };
300 + name = Profile;
301 + };
302 + 97C147031CF9000F007C117D /* Debug */ = {
303 + isa = XCBuildConfiguration;
304 + buildSettings = {
305 + ALWAYS_SEARCH_USER_PATHS = NO;
306 + CLANG_ANALYZER_NONNULL = YES;
307 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
308 + CLANG_CXX_LIBRARY = "libc++";
309 + CLANG_ENABLE_MODULES = YES;
310 + CLANG_ENABLE_OBJC_ARC = YES;
311 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
312 + CLANG_WARN_BOOL_CONVERSION = YES;
313 + CLANG_WARN_COMMA = YES;
314 + CLANG_WARN_CONSTANT_CONVERSION = YES;
315 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
316 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
317 + CLANG_WARN_EMPTY_BODY = YES;
318 + CLANG_WARN_ENUM_CONVERSION = YES;
319 + CLANG_WARN_INFINITE_RECURSION = YES;
320 + CLANG_WARN_INT_CONVERSION = YES;
321 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
322 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
323 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
324 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
325 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
326 + CLANG_WARN_STRICT_PROTOTYPES = YES;
327 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
328 + CLANG_WARN_UNREACHABLE_CODE = YES;
329 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
330 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
331 + COPY_PHASE_STRIP = NO;
332 + DEBUG_INFORMATION_FORMAT = dwarf;
333 + ENABLE_STRICT_OBJC_MSGSEND = YES;
334 + ENABLE_TESTABILITY = YES;
335 + GCC_C_LANGUAGE_STANDARD = gnu99;
336 + GCC_DYNAMIC_NO_PIC = NO;
337 + GCC_NO_COMMON_BLOCKS = YES;
338 + GCC_OPTIMIZATION_LEVEL = 0;
339 + GCC_PREPROCESSOR_DEFINITIONS = (
340 + "DEBUG=1",
341 + "$(inherited)",
342 + );
343 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
344 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
345 + GCC_WARN_UNDECLARED_SELECTOR = YES;
346 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
347 + GCC_WARN_UNUSED_FUNCTION = YES;
348 + GCC_WARN_UNUSED_VARIABLE = YES;
349 + IPHONEOS_DEPLOYMENT_TARGET = 9.0;
350 + MTL_ENABLE_DEBUG_INFO = YES;
351 + ONLY_ACTIVE_ARCH = YES;
352 + SDKROOT = iphoneos;
353 + TARGETED_DEVICE_FAMILY = "1,2";
354 + };
355 + name = Debug;
356 + };
357 + 97C147041CF9000F007C117D /* Release */ = {
358 + isa = XCBuildConfiguration;
359 + buildSettings = {
360 + ALWAYS_SEARCH_USER_PATHS = NO;
361 + CLANG_ANALYZER_NONNULL = YES;
362 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
363 + CLANG_CXX_LIBRARY = "libc++";
364 + CLANG_ENABLE_MODULES = YES;
365 + CLANG_ENABLE_OBJC_ARC = YES;
366 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
367 + CLANG_WARN_BOOL_CONVERSION = YES;
368 + CLANG_WARN_COMMA = YES;
369 + CLANG_WARN_CONSTANT_CONVERSION = YES;
370 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
371 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
372 + CLANG_WARN_EMPTY_BODY = YES;
373 + CLANG_WARN_ENUM_CONVERSION = YES;
374 + CLANG_WARN_INFINITE_RECURSION = YES;
375 + CLANG_WARN_INT_CONVERSION = YES;
376 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
377 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
378 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
379 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
380 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
381 + CLANG_WARN_STRICT_PROTOTYPES = YES;
382 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
383 + CLANG_WARN_UNREACHABLE_CODE = YES;
384 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
385 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
386 + COPY_PHASE_STRIP = NO;
387 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
388 + ENABLE_NS_ASSERTIONS = NO;
389 + ENABLE_STRICT_OBJC_MSGSEND = YES;
390 + GCC_C_LANGUAGE_STANDARD = gnu99;
391 + GCC_NO_COMMON_BLOCKS = YES;
392 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
393 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
394 + GCC_WARN_UNDECLARED_SELECTOR = YES;
395 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
396 + GCC_WARN_UNUSED_FUNCTION = YES;
397 + GCC_WARN_UNUSED_VARIABLE = YES;
398 + IPHONEOS_DEPLOYMENT_TARGET = 9.0;
399 + MTL_ENABLE_DEBUG_INFO = NO;
400 + SDKROOT = iphoneos;
401 + SUPPORTED_PLATFORMS = iphoneos;
402 + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
403 + TARGETED_DEVICE_FAMILY = "1,2";
404 + VALIDATE_PRODUCT = YES;
405 + };
406 + name = Release;
407 + };
408 + 97C147061CF9000F007C117D /* Debug */ = {
409 + isa = XCBuildConfiguration;
410 + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
411 + buildSettings = {
412 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
413 + CLANG_ENABLE_MODULES = YES;
414 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
415 + ENABLE_BITCODE = NO;
416 + INFOPLIST_FILE = Runner/Info.plist;
417 + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
418 + PRODUCT_BUNDLE_IDENTIFIER = com.example.like;
419 + PRODUCT_NAME = "$(TARGET_NAME)";
420 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
421 + SWIFT_OPTIMIZATION_LEVEL = "-Onone";
422 + SWIFT_VERSION = 5.0;
423 + VERSIONING_SYSTEM = "apple-generic";
424 + };
425 + name = Debug;
426 + };
427 + 97C147071CF9000F007C117D /* Release */ = {
428 + isa = XCBuildConfiguration;
429 + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
430 + buildSettings = {
431 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
432 + CLANG_ENABLE_MODULES = YES;
433 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
434 + ENABLE_BITCODE = NO;
435 + INFOPLIST_FILE = Runner/Info.plist;
436 + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
437 + PRODUCT_BUNDLE_IDENTIFIER = com.example.like;
438 + PRODUCT_NAME = "$(TARGET_NAME)";
439 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
440 + SWIFT_VERSION = 5.0;
441 + VERSIONING_SYSTEM = "apple-generic";
442 + };
443 + name = Release;
444 + };
445 +/* End XCBuildConfiguration section */
446 +
447 +/* Begin XCConfigurationList section */
448 + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
449 + isa = XCConfigurationList;
450 + buildConfigurations = (
451 + 97C147031CF9000F007C117D /* Debug */,
452 + 97C147041CF9000F007C117D /* Release */,
453 + 249021D3217E4FDB00AE95B9 /* Profile */,
454 + );
455 + defaultConfigurationIsVisible = 0;
456 + defaultConfigurationName = Release;
457 + };
458 + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
459 + isa = XCConfigurationList;
460 + buildConfigurations = (
461 + 97C147061CF9000F007C117D /* Debug */,
462 + 97C147071CF9000F007C117D /* Release */,
463 + 249021D4217E4FDB00AE95B9 /* Profile */,
464 + );
465 + defaultConfigurationIsVisible = 0;
466 + defaultConfigurationName = Release;
467 + };
468 +/* End XCConfigurationList section */
469 + };
470 + rootObject = 97C146E61CF9000F007C117D /* Project object */;
471 +}
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<Workspace
3 + version = "1.0">
4 + <FileRef
5 + location = "self:">
6 + </FileRef>
7 +</Workspace>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 +<plist version="1.0">
4 +<dict>
5 + <key>IDEDidComputeMac32BitWarning</key>
6 + <true/>
7 +</dict>
8 +</plist>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 +<plist version="1.0">
4 +<dict>
5 + <key>PreviewsEnabled</key>
6 + <false/>
7 +</dict>
8 +</plist>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<Scheme
3 + LastUpgradeVersion = "1020"
4 + version = "1.3">
5 + <BuildAction
6 + parallelizeBuildables = "YES"
7 + buildImplicitDependencies = "YES">
8 + <BuildActionEntries>
9 + <BuildActionEntry
10 + buildForTesting = "YES"
11 + buildForRunning = "YES"
12 + buildForProfiling = "YES"
13 + buildForArchiving = "YES"
14 + buildForAnalyzing = "YES">
15 + <BuildableReference
16 + BuildableIdentifier = "primary"
17 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
18 + BuildableName = "Runner.app"
19 + BlueprintName = "Runner"
20 + ReferencedContainer = "container:Runner.xcodeproj">
21 + </BuildableReference>
22 + </BuildActionEntry>
23 + </BuildActionEntries>
24 + </BuildAction>
25 + <TestAction
26 + buildConfiguration = "Debug"
27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29 + shouldUseLaunchSchemeArgsEnv = "YES">
30 + <Testables>
31 + </Testables>
32 + <MacroExpansion>
33 + <BuildableReference
34 + BuildableIdentifier = "primary"
35 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
36 + BuildableName = "Runner.app"
37 + BlueprintName = "Runner"
38 + ReferencedContainer = "container:Runner.xcodeproj">
39 + </BuildableReference>
40 + </MacroExpansion>
41 + <AdditionalOptions>
42 + </AdditionalOptions>
43 + </TestAction>
44 + <LaunchAction
45 + buildConfiguration = "Debug"
46 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
47 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
48 + launchStyle = "0"
49 + useCustomWorkingDirectory = "NO"
50 + ignoresPersistentStateOnLaunch = "NO"
51 + debugDocumentVersioning = "YES"
52 + debugServiceExtension = "internal"
53 + allowLocationSimulation = "YES">
54 + <BuildableProductRunnable
55 + runnableDebuggingMode = "0">
56 + <BuildableReference
57 + BuildableIdentifier = "primary"
58 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
59 + BuildableName = "Runner.app"
60 + BlueprintName = "Runner"
61 + ReferencedContainer = "container:Runner.xcodeproj">
62 + </BuildableReference>
63 + </BuildableProductRunnable>
64 + <AdditionalOptions>
65 + </AdditionalOptions>
66 + </LaunchAction>
67 + <ProfileAction
68 + buildConfiguration = "Profile"
69 + shouldUseLaunchSchemeArgsEnv = "YES"
70 + savedToolIdentifier = ""
71 + useCustomWorkingDirectory = "NO"
72 + debugDocumentVersioning = "YES">
73 + <BuildableProductRunnable
74 + runnableDebuggingMode = "0">
75 + <BuildableReference
76 + BuildableIdentifier = "primary"
77 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
78 + BuildableName = "Runner.app"
79 + BlueprintName = "Runner"
80 + ReferencedContainer = "container:Runner.xcodeproj">
81 + </BuildableReference>
82 + </BuildableProductRunnable>
83 + </ProfileAction>
84 + <AnalyzeAction
85 + buildConfiguration = "Debug">
86 + </AnalyzeAction>
87 + <ArchiveAction
88 + buildConfiguration = "Release"
89 + revealArchiveInOrganizer = "YES">
90 + </ArchiveAction>
91 +</Scheme>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<Workspace
3 + version = "1.0">
4 + <FileRef
5 + location = "group:Runner.xcodeproj">
6 + </FileRef>
7 +</Workspace>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 +<plist version="1.0">
4 +<dict>
5 + <key>IDEDidComputeMac32BitWarning</key>
6 + <true/>
7 +</dict>
8 +</plist>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 +<plist version="1.0">
4 +<dict>
5 + <key>PreviewsEnabled</key>
6 + <false/>
7 +</dict>
8 +</plist>
1 +import UIKit
2 +import Flutter
3 +
4 +@UIApplicationMain
5 +@objc class AppDelegate: FlutterAppDelegate {
6 + override func application(
7 + _ application: UIApplication,
8 + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 + ) -> Bool {
10 + GeneratedPluginRegistrant.register(with: self)
11 + return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 + }
13 +}
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 +}
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 +}
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.
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3 + <dependencies>
4 + <deployment identifier="iOS"/>
5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
6 + </dependencies>
7 + <scenes>
8 + <!--View Controller-->
9 + <scene sceneID="EHf-IW-A2E">
10 + <objects>
11 + <viewController id="01J-lp-oVM" sceneMemberID="viewController">
12 + <layoutGuides>
13 + <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
14 + <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
15 + </layoutGuides>
16 + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
17 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18 + <subviews>
19 + <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
20 + </imageView>
21 + </subviews>
22 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
23 + <constraints>
24 + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
25 + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
26 + </constraints>
27 + </view>
28 + </viewController>
29 + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
30 + </objects>
31 + <point key="canvasLocation" x="53" y="375"/>
32 + </scene>
33 + </scenes>
34 + <resources>
35 + <image name="LaunchImage" width="168" height="185"/>
36 + </resources>
37 +</document>
1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
3 + <dependencies>
4 + <deployment identifier="iOS"/>
5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
6 + </dependencies>
7 + <scenes>
8 + <!--Flutter View Controller-->
9 + <scene sceneID="tne-QT-ifu">
10 + <objects>
11 + <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
12 + <layoutGuides>
13 + <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
14 + <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
15 + </layoutGuides>
16 + <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
17 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
18 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
19 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
20 + </view>
21 + </viewController>
22 + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
23 + </objects>
24 + </scene>
25 + </scenes>
26 +</document>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 +<plist version="1.0">
4 +<dict>
5 + <key>CFBundleDevelopmentRegion</key>
6 + <string>$(DEVELOPMENT_LANGUAGE)</string>
7 + <key>CFBundleExecutable</key>
8 + <string>$(EXECUTABLE_NAME)</string>
9 + <key>CFBundleIdentifier</key>
10 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 + <key>CFBundleInfoDictionaryVersion</key>
12 + <string>6.0</string>
13 + <key>CFBundleName</key>
14 + <string>like</string>
15 + <key>CFBundlePackageType</key>
16 + <string>APPL</string>
17 + <key>CFBundleShortVersionString</key>
18 + <string>$(FLUTTER_BUILD_NAME)</string>
19 + <key>CFBundleSignature</key>
20 + <string>????</string>
21 + <key>CFBundleVersion</key>
22 + <string>$(FLUTTER_BUILD_NUMBER)</string>
23 + <key>LSRequiresIPhoneOS</key>
24 + <true/>
25 + <key>UILaunchStoryboardName</key>
26 + <string>LaunchScreen</string>
27 + <key>UIMainStoryboardFile</key>
28 + <string>Main</string>
29 + <key>UISupportedInterfaceOrientations</key>
30 + <array>
31 + <string>UIInterfaceOrientationPortrait</string>
32 + <string>UIInterfaceOrientationLandscapeLeft</string>
33 + <string>UIInterfaceOrientationLandscapeRight</string>
34 + </array>
35 + <key>UISupportedInterfaceOrientations~ipad</key>
36 + <array>
37 + <string>UIInterfaceOrientationPortrait</string>
38 + <string>UIInterfaceOrientationPortraitUpsideDown</string>
39 + <string>UIInterfaceOrientationLandscapeLeft</string>
40 + <string>UIInterfaceOrientationLandscapeRight</string>
41 + </array>
42 + <key>UIViewControllerBasedStatusBarAppearance</key>
43 + <false/>
44 +</dict>
45 +</plist>
1 +#import "GeneratedPluginRegistrant.h"
1 +import 'package:dio/dio.dart';
2 +import 'package:dio_cookie_manager/dio_cookie_manager.dart';
3 +import 'package:cookie_jar/cookie_jar.dart';
4 +
5 +//network
6 +var cookieJar = CookieJar();
7 +var dio = Dio()
8 + ..options.baseUrl = "http://172.18.5.174:3000/"
9 + ..interceptors.add(CookieManager(cookieJar))
10 + ..options.receiveTimeout = 15000
11 + ..options.connectTimeout = 15000;
12 +
13 +var strapiAddress = "http://172.18.5.174:3000/";
...\ No newline at end of file ...\ No newline at end of file
1 +import 'package:flutter/material.dart';
2 +import 'package:like/screens/home_page.dart';
3 +import 'package:like/screens/login/login.dart';
4 +import 'package:like/screens/login/signup.dart';
5 +import 'package:like/env.dart';
6 +void main() {
7 + runApp(TC());
8 +}
9 +
10 +
11 +/*
12 +class MyApp extends StatelessWidget {
13 + const MyApp({Key? key}) : super(key: key);
14 +*/
15 +
16 +class TC extends StatelessWidget {
17 + @override
18 + Widget build(BuildContext context) {
19 + return MaterialApp(
20 + title: 'like Project',
21 + initialRoute: '/login',
22 + debugShowCheckedModeBanner: false,
23 + routes: {
24 + '/': (context) => HomePage(),
25 + '/login': (context) => LoginPage(),
26 + '/signup' :(context) => SignupPage(),
27 + },
28 + );
29 + }
30 +}
31 +/*
32 + // This widget is the root of your application.
33 + @override
34 + Widget build(BuildContext context) {
35 + return MaterialApp(
36 + title: 'Flutter Demo',
37 + theme: ThemeData(
38 +
39 + primarySwatch: Colors.blue,
40 + ),
41 + home: const MyHomePage(title: 'Flutter Demo Home Page'),
42 + );
43 + }
44 +}
45 +
46 +
47 +class MyHomePage extends StatefulWidget {
48 + const MyHomePage({Key? key, required this.title}) : super(key: key);
49 +
50 +
51 + final String title;
52 +
53 + @override
54 + State<MyHomePage> createState() => _MyHomePageState();
55 +}
56 +
57 +class _MyHomePageState extends State<MyHomePage> {
58 + int _counter = 0;
59 +
60 + void _incrementCounter() {
61 + setState(() {
62 + // This call to setState tells the Flutter framework that something has
63 + // changed in this State, which causes it to rerun the build method below
64 + // so that the display can reflect the updated values. If we changed
65 + // _counter without calling setState(), then the build method would not be
66 + // called again, and so nothing would appear to happen.
67 + _counter++;
68 + });
69 + }
70 +
71 + @override
72 + Widget build(BuildContext context) {
73 + // This method is rerun every time setState is called, for instance as done
74 + // by the _incrementCounter method above.
75 + //
76 + // The Flutter framework has been optimized to make rerunning build methods
77 + // fast, so that you can just rebuild anything that needs updating rather
78 + // than having to individually change instances of widgets.
79 + return Scaffold(
80 + appBar: AppBar(
81 + // Here we take the value from the MyHomePage object that was created by
82 + // the App.build method, and use it to set our appbar title.
83 + title: Text(widget.title),
84 + ),
85 + body: Center(
86 + // Center is a layout widget. It takes a single child and positions it
87 + // in the middle of the parent.
88 + child: Column(
89 + // Column is also a layout widget. It takes a list of children and
90 + // arranges them vertically. By default, it sizes itself to fit its
91 + // children horizontally, and tries to be as tall as its parent.
92 + //
93 + // Invoke "debug painting" (press "p" in the console, choose the
94 + // "Toggle Debug Paint" action from the Flutter Inspector in Android
95 + // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
96 + // to see the wireframe for each widget.
97 + //
98 + // Column has various properties to control how it sizes itself and
99 + // how it positions its children. Here we use mainAxisAlignment to
100 + // center the children vertically; the main axis here is the vertical
101 + // axis because Columns are vertical (the cross axis would be
102 + // horizontal).
103 + mainAxisAlignment: MainAxisAlignment.center,
104 + children: <Widget>[
105 + const Text(
106 + 'You have pushed the button this many times:',
107 + ),
108 + Text(
109 + '$_counter',
110 + style: Theme.of(context).textTheme.headline4,
111 + ),
112 + ],
113 + ),
114 + ),
115 + floatingActionButton: FloatingActionButton(
116 + onPressed: _incrementCounter,
117 + tooltip: 'Increment',
118 + child: const Icon(Icons.add),
119 + ), // This trailing comma makes auto-formatting nicer for build methods.
120 + );
121 + }
122 +}
123 +*/
...\ No newline at end of file ...\ No newline at end of file
File mode changed
File mode changed
1 +import 'dart:core';
2 +import 'package:flutter/material.dart';
3 +import 'dart:convert';
4 +
5 +User userFromJson(String str) => User.fromJson(json.decode(str));
6 +
7 +String userToJson(User data) => json.encode(data.toJson());
8 +
9 +class User {
10 +
11 + String email;
12 + String password;
13 + String phone;
14 + String token;
15 + String username;
16 + List<String> books;
17 + List<String> favorite;
18 +
19 + User(
20 + this.email,
21 + this.password,
22 + this.phone,
23 + this.token,
24 + this.username,
25 + this.books,
26 + this.favorite
27 + );
28 +
29 +
30 + User.fromJson(Map<String, dynamic> json)
31 + :
32 + token = json["token"],
33 + email=json["email"],
34 + password= json["password"],
35 + phone=json["phone"],
36 + username= json["username"],
37 + books=List<String>.from(json["books"].map((x) => x)),
38 + favorite= List<String>.from(json["favorite"].map((x) => x));
39 +
40 +
41 + Map<String, dynamic> toJson() => {
42 + "email": email,
43 + "password": password,
44 + "phone": phone,
45 + "username": username,
46 + "books": List<dynamic>.from(books.map((x) => x)),
47 + "favorite": List<dynamic>.from(favorite.map((x) => x))
48 + };
49 +
50 + void update(var user) {
51 + // String username, List<String> address, String phone,
52 + // List<String> pets, List<String> favorites
53 + this.email = user["email"] ?? this.email;
54 + this.username = user["nickname"] ?? this.username;
55 + //수정필요
56 +
57 +
58 + this.phone = user["phone"] ?? this.phone;
59 + // this._pets =
60 + // user["pets"] == null ? this._pets : List<String>.from(user["pets"]);
61 +
62 + this.books = (user["books"] == null)
63 + ? this.books
64 + : List<String>.from(user["books"]);
65 +
66 + this.favorite = (user["favorite"] == null)
67 + ? this.favorite
68 + : List<String>.from(user["favorite"]);
69 +
70 + print("user update");
71 + //notifyListeners();
72 + }
73 +}
74 +
75 +
76 +//user provider
77 +//pets provider
78 +/*
79 +class User with ChangeNotifier {
80 + String _email;
81 + String get email => _email;
82 + set email(String email) => _email = email;
83 + String _username;
84 + String get username => _username;
85 + set username(String username) => _username = username;
86 +
87 + String _phone;
88 + String get phone => _phone;
89 + set phone(String phone) => _phone = phone;
90 + List<String> _books = List<String>(5);
91 + List<String> get _books => _pets;
92 + List<String> _favorite = List<String>();
93 + List<String> get favorite => _favorites;
94 +
95 +
96 + void updatefavorite(String contentsID){
97 + this._favorite.add(contentsID);
98 + }
99 + void deletefavorite(String contentsID){
100 + this._favorite.remove(contentsID);
101 + }
102 + void update(var user) {
103 + // String username, List<String> address, String phone,
104 + // List<String> pets, List<String> favorites
105 + this._email = user["email"] ?? this._email;
106 + this._username = user["nickname"] ?? this._username;
107 + //수정필요
108 +
109 +
110 + this._phone = user["phone"] ?? this._phone;
111 + // this._pets =
112 + // user["pets"] == null ? this._pets : List<String>.from(user["pets"]);
113 +
114 + this._books = (user["books"] == null)
115 + ? this._books
116 + : List<String>.from(user["books"]);
117 +
118 + this._favorite = (user["favorite"] == null)
119 + ? this._favorite
120 + : List<String>.from(user["favorite"]);
121 +
122 + print("user update");
123 + //notifyListeners();
124 + }
125 +}*/
...\ No newline at end of file ...\ No newline at end of file
1 +import 'package:like/widgets/bottom_bar.dart';
2 +import 'package:like/widgets/carousel.dart';
3 +import 'package:like/widgets/destination_heading.dart';
4 +import 'package:like/widgets/explore_drawer.dart';
5 +import 'package:like/widgets/featured_heading.dart';
6 +import 'package:like/widgets/featured_tiles.dart';
7 +import 'package:like/widgets/floating_quick_access_bar.dart';
8 +import 'package:like/widgets/responsive.dart';
9 +import 'package:like/widgets/top_bar_contents.dart';
10 +import 'package:flutter/material.dart';
11 +
12 +class HomePage extends StatefulWidget {
13 + @override
14 + _HomePageState createState() => _HomePageState();
15 +}
16 +
17 +class _HomePageState extends State<HomePage> {
18 + final ScrollController _scrollController = ScrollController();
19 + double _scrollPosition = 0;
20 + double _opacity = 0;
21 +
22 + _scrollListener() {
23 + setState(() {
24 + _scrollPosition = _scrollController.position.pixels;
25 + });
26 + }
27 +
28 + @override
29 + void initState() {
30 + _scrollController.addListener(_scrollListener);
31 + super.initState();
32 + }
33 +
34 + @override
35 + Widget build(BuildContext context) {
36 + var screenSize = MediaQuery.of(context).size;
37 + _opacity = _scrollPosition < screenSize.height * 0.40
38 + ? _scrollPosition / (screenSize.height * 0.40)
39 + : 1;
40 +
41 + return Scaffold(
42 + extendBodyBehindAppBar: true,
43 + appBar: ResponsiveWidget.isSmallScreen(context)
44 + ? AppBar(
45 + backgroundColor: Colors.blueGrey.shade900.withOpacity(_opacity),
46 + elevation: 0,
47 + title: Text(
48 + 'EXPLORE',
49 + style: TextStyle(
50 + color: Colors.blueGrey.shade100,
51 + fontSize: 20,
52 + fontFamily: 'Montserrat',
53 + fontWeight: FontWeight.w400,
54 + letterSpacing: 3,
55 + ),
56 + ),
57 + )
58 + : PreferredSize(
59 + preferredSize: Size(screenSize.width, 1000),
60 + child: TopBarContents(_opacity),
61 + ),
62 + drawer: ExploreDrawer(),
63 + body: SingleChildScrollView(
64 + controller: _scrollController,
65 + physics: ClampingScrollPhysics(),
66 + child: Column(
67 + children: [
68 + Stack(
69 + children: [
70 + Container(
71 + child: SizedBox(
72 + height: screenSize.height * 0.45,
73 + width: screenSize.width,
74 + child: Image.asset(
75 + 'assets/images/cover.jpg',
76 + fit: BoxFit.cover,
77 + ),
78 + ),
79 + ),
80 + Column(
81 + children: [
82 + FloatingQuickAccessBar(screenSize: screenSize),
83 + Container(
84 + child: Column(
85 + children: [
86 + FeaturedHeading(
87 + screenSize: screenSize,
88 + ),
89 + FeaturedTiles(screenSize: screenSize)
90 + ],
91 + ),
92 + ),
93 + ],
94 + )
95 + ],
96 + ),
97 + DestinationHeading(screenSize: screenSize),
98 + DestinationCarousel(),
99 + SizedBox(height: screenSize.height / 10),
100 + BottomBar(),
101 + ],
102 + ),
103 + ),
104 + );
105 + }
106 +}
...\ No newline at end of file ...\ No newline at end of file
1 +import 'package:flutter/material.dart';
2 +import 'package:flutter/services.dart';
3 +
4 +class LoginPage extends StatefulWidget {
5 + @override
6 + State<StatefulWidget> createState() {
7 + return _LoginPageState();
8 + }
9 +}
10 +
11 +class _LoginPageState extends State<LoginPage> {
12 +
13 + @override
14 + void initState() {
15 + SystemChrome.setEnabledSystemUIOverlays([]);
16 + super.initState();
17 + }
18 +
19 + @override
20 + Widget build(BuildContext context) {
21 + return Scaffold(
22 + body: Container(
23 + child: ListView(
24 + children: <Widget>[
25 + Container(
26 + width: MediaQuery.of(context).size.width,
27 + height: MediaQuery.of(context).size.height/3.5,
28 + decoration: BoxDecoration(
29 + gradient: LinearGradient(
30 + begin: Alignment.topCenter,
31 + end: Alignment.bottomCenter,
32 + colors: [
33 + Color(0xff6bceff),
34 + Color(0xff6bceff)
35 + ],
36 + ),
37 + borderRadius: BorderRadius.only(
38 + bottomLeft: Radius.circular(90)
39 + )
40 + ),
41 + child: Column(
42 + mainAxisAlignment: MainAxisAlignment.center,
43 + children: <Widget>[
44 + Spacer(),
45 + Align(
46 + alignment: Alignment.center,
47 + child: Icon(Icons.person,
48 + size: 90,
49 + color: Colors.white,
50 + ),
51 + ),
52 + Spacer(),
53 +
54 + Align(
55 + alignment: Alignment.bottomRight,
56 + child: Padding(
57 + padding: const EdgeInsets.only(
58 + bottom: 32,
59 + right: 32
60 + ),
61 + child: Text('Login',
62 + style: TextStyle(
63 + color: Colors.white,
64 + fontSize: 18
65 + ),
66 + ),
67 + ),
68 + ),
69 + ],
70 + ),
71 + ),
72 +
73 + Container(
74 + height: MediaQuery.of(context).size.height/2,
75 + width: MediaQuery.of(context).size.width,
76 + padding: EdgeInsets.only(top: 62),
77 + child: Column(
78 + children: <Widget>[
79 + Container(
80 + width: MediaQuery.of(context).size.width/1.2,
81 + height: 45,
82 + padding: EdgeInsets.only(
83 + top: 4,left: 16, right: 16, bottom: 4
84 + ),
85 + decoration: BoxDecoration(
86 + borderRadius: BorderRadius.all(
87 + Radius.circular(50)
88 + ),
89 + color: Colors.white,
90 + boxShadow: [
91 + BoxShadow(
92 + color: Colors.black12,
93 + blurRadius: 5
94 + )
95 + ]
96 + ),
97 + child: TextField(
98 + decoration: InputDecoration(
99 + border: InputBorder.none,
100 + icon: Icon(Icons.person,
101 + color: Color(0xff6bceff),
102 + ),
103 + hintText: 'Username',
104 + ),
105 + ),
106 + ),
107 +
108 + Container(
109 + width: MediaQuery.of(context).size.width/1.2,
110 + height: 45,
111 + margin: EdgeInsets.only(top: 32),
112 + padding: EdgeInsets.only(
113 + top: 4,left: 16, right: 16, bottom: 4
114 + ),
115 + decoration: BoxDecoration(
116 + borderRadius: BorderRadius.all(
117 + Radius.circular(50)
118 + ),
119 + color: Colors.white,
120 + boxShadow: [
121 + BoxShadow(
122 + color: Colors.black12,
123 + blurRadius: 5
124 + )
125 + ]
126 + ),
127 + child: TextField(
128 + obscureText: true,
129 + decoration: InputDecoration(
130 + border: InputBorder.none,
131 + icon: Icon(Icons.vpn_key,
132 + color: Color(0xff6bceff),
133 + ),
134 + hintText: 'Password',
135 + ),
136 + ),
137 + ),
138 +
139 + Align(
140 + alignment: Alignment.centerRight,
141 + child: Padding(
142 + padding: const EdgeInsets.only(
143 + top: 16, right: 32
144 + ),
145 + child: Text('Forgot Password ?',
146 + style: TextStyle(
147 + color: Colors.grey
148 + ),
149 + ),
150 + ),
151 + ),
152 + Spacer(),
153 +
154 + InkWell(
155 + onTap: (){
156 + Navigator.pushNamed(context, '/');
157 + },
158 + child: Container(
159 + height: 45,
160 + width: MediaQuery.of(context).size.width/1.2,
161 + decoration: BoxDecoration(
162 + gradient: LinearGradient(
163 + colors: [
164 + Color(0xff6bceff),
165 + Color(0xFF00abff),
166 + ],
167 + ),
168 + borderRadius: BorderRadius.all(
169 + Radius.circular(50)
170 + )
171 + ),
172 + child: Center(
173 + child: Text('Login'.toUpperCase(),
174 + style: TextStyle(
175 + color: Colors.white,
176 + fontWeight: FontWeight.bold
177 + ),
178 + ),
179 + ),
180 + ),
181 + ),
182 + ],
183 + ),
184 + ),
185 + SizedBox(
186 + height: 50,
187 + ),
188 + InkWell(
189 + child: Row(
190 + mainAxisAlignment: MainAxisAlignment.center,
191 + children: <Widget>[
192 + Text("Dnon't have an account ?"),
193 + Text("Sign Up",style: TextStyle(color: Color(0xff6bceff)),),
194 + ],
195 + ),
196 + onTap: (){
197 + Navigator.pushNamed(context, '/signup');
198 + },
199 + ),
200 + ],
201 +
202 + ),
203 + ),
204 + );
205 + }
206 +}
...\ No newline at end of file ...\ No newline at end of file
1 +import 'package:flutter/material.dart';
2 +import 'package:flutter/services.dart';
3 +
4 +class SignupPage extends StatefulWidget {
5 + @override
6 + _SignupPageState createState() => _SignupPageState();
7 +}
8 +
9 +class _SignupPageState extends State<SignupPage> {
10 +
11 + @override
12 + void initState() {
13 + SystemChrome.setEnabledSystemUIOverlays([]);
14 + super.initState();
15 + }
16 +
17 + @override
18 + Widget build(BuildContext context) {
19 + return Scaffold(
20 + body: Container(
21 + child: ListView(
22 + children: <Widget>[
23 + Container(
24 + width: MediaQuery.of(context).size.width,
25 + height: MediaQuery.of(context).size.height/3.5,
26 + decoration: BoxDecoration(
27 + gradient: LinearGradient(
28 + begin: Alignment.topCenter,
29 + end: Alignment.bottomCenter,
30 + colors: [
31 + Color(0xff6bceff),
32 + Color(0xff6bceff)
33 + ],
34 + ),
35 + borderRadius: BorderRadius.only(
36 + bottomLeft: Radius.circular(90)
37 + )
38 + ),
39 + child: Column(
40 + mainAxisAlignment: MainAxisAlignment.center,
41 + children: <Widget>[
42 + Spacer(),
43 + Align(
44 + alignment: Alignment.center,
45 + child: Icon(Icons.person,
46 + size: 90,
47 + color: Colors.white,
48 + ),
49 + ),
50 + Spacer(),
51 +
52 + Align(
53 + alignment: Alignment.bottomRight,
54 + child: Padding(
55 + padding: const EdgeInsets.only(
56 + bottom: 32,
57 + right: 32
58 + ),
59 + child: Text('Sign Up',
60 + style: TextStyle(
61 + color: Colors.white,
62 + fontSize: 18
63 + ),
64 + ),
65 + ),
66 + ),
67 + ],
68 + ),
69 + ),
70 +
71 + Container(
72 + height: MediaQuery.of(context).size.height/2,
73 + width: MediaQuery.of(context).size.width,
74 + padding: EdgeInsets.only(top: 62),
75 + child: Column(
76 + children: <Widget>[
77 + Container(
78 + width: MediaQuery.of(context).size.width/1.2,
79 + height: 45,
80 + padding: EdgeInsets.only(
81 + top: 4,left: 16, right: 16, bottom: 4
82 + ),
83 + decoration: BoxDecoration(
84 + borderRadius: BorderRadius.all(
85 + Radius.circular(50)
86 + ),
87 + color: Colors.white,
88 + boxShadow: [
89 + BoxShadow(
90 + color: Colors.black12,
91 + blurRadius: 5
92 + )
93 + ]
94 + ),
95 + child: TextField(
96 + decoration: InputDecoration(
97 + border: InputBorder.none,
98 + hintText: 'Full Name',
99 + ),
100 + ),
101 + ),
102 + SizedBox(
103 + height: 5,
104 + ),
105 + Container(
106 + width: MediaQuery.of(context).size.width/1.2,
107 + height: 45,
108 + padding: EdgeInsets.only(
109 + top: 4,left: 16, right: 16, bottom: 4
110 + ),
111 + decoration: BoxDecoration(
112 + borderRadius: BorderRadius.all(
113 + Radius.circular(50)
114 + ),
115 + color: Colors.white,
116 + boxShadow: [
117 + BoxShadow(
118 + color: Colors.black12,
119 + blurRadius: 5
120 + )
121 + ]
122 + ),
123 + child: TextField(
124 + decoration: InputDecoration(
125 + border: InputBorder.none,
126 + hintText: 'Username',
127 + ),
128 + ),
129 + ),
130 + SizedBox(
131 + height: 5,
132 + ),
133 + Container(
134 + width: MediaQuery.of(context).size.width/1.2,
135 + height: 45,
136 + padding: EdgeInsets.only(
137 + top: 4,left: 16, right: 16, bottom: 4
138 + ),
139 + decoration: BoxDecoration(
140 + borderRadius: BorderRadius.all(
141 + Radius.circular(50)
142 + ),
143 + color: Colors.white,
144 + boxShadow: [
145 + BoxShadow(
146 + color: Colors.black12,
147 + blurRadius: 5
148 + )
149 + ]
150 + ),
151 + child: TextField(
152 + decoration: InputDecoration(
153 + border: InputBorder.none,
154 + hintText: 'Email',
155 + ),
156 + ),
157 + ),
158 + SizedBox(
159 + height: 5,
160 + ),
161 + Container(
162 + width: MediaQuery.of(context).size.width/1.2,
163 + height: 45,
164 + padding: EdgeInsets.only(
165 + top: 4,left: 16, right: 16, bottom: 4
166 + ),
167 + decoration: BoxDecoration(
168 + borderRadius: BorderRadius.all(
169 + Radius.circular(50)
170 + ),
171 + color: Colors.white,
172 + boxShadow: [
173 + BoxShadow(
174 + color: Colors.black12,
175 + blurRadius: 5
176 + )
177 + ]
178 + ),
179 + child: TextField(
180 + obscureText: true,
181 + decoration: InputDecoration(
182 + border: InputBorder.none,
183 + hintText: 'Password',
184 + ),
185 + ),
186 + ),
187 + SizedBox(
188 + height: 15,
189 + ),
190 + InkWell(
191 + onTap: (){
192 + Navigator.pushNamed(context, '/');
193 + },
194 + child: Container(
195 + height: 45,
196 + width: MediaQuery.of(context).size.width/1.2,
197 + decoration: BoxDecoration(
198 + gradient: LinearGradient(
199 + colors: [
200 + Color(0xff6bceff),
201 + Color(0xFF00abff),
202 + ],
203 + ),
204 + borderRadius: BorderRadius.all(
205 + Radius.circular(50)
206 + )
207 + ),
208 + child: Center(
209 + child: Text('Sign Up'.toUpperCase(),
210 + style: TextStyle(
211 + color: Colors.white,
212 + fontWeight: FontWeight.bold
213 + ),
214 + ),
215 + ),
216 + ),
217 + ),
218 + ],
219 + ),
220 + ),
221 +
222 + InkWell(
223 + child: Row(
224 + mainAxisAlignment: MainAxisAlignment.center,
225 + children: <Widget>[
226 + Text("Have an account ?"),
227 + Text("Login",style: TextStyle(color: Color(0xff6bceff)),),
228 + ],
229 + ),
230 + onTap: (){
231 + Navigator.pop(context);
232 + },
233 + ),
234 + ],
235 +
236 + ),
237 + ),
238 + );
239 + }
240 +}
...\ No newline at end of file ...\ No newline at end of file
1 +import 'package:firebase_auth/firebase_auth.dart';
2 +import 'package:firebase_core/firebase_core.dart';
3 +import 'package:google_sign_in/google_sign_in.dart';
4 +import 'package:shared_preferences/shared_preferences.dart';
5 +import 'package:flutter/foundation.dart' show kIsWeb;
6 +
7 +final FirebaseAuth _auth = FirebaseAuth.instance;
8 +final GoogleSignIn googleSignIn = GoogleSignIn();
9 +
10 +String? uid;
11 +String? name;
12 +String? userEmail;
13 +String? imageUrl;
14 +
15 +/// For checking if the user is already signed into the
16 +/// app using Google Sign In
17 +Future getUser() async {
18 + await Firebase.initializeApp();
19 +
20 + SharedPreferences prefs = await SharedPreferences.getInstance();
21 + bool authSignedIn = prefs.getBool('auth') ?? false;
22 +
23 + final User? user = _auth.currentUser;
24 +
25 + if (authSignedIn == true) {
26 + if (user != null) {
27 + uid = user.uid;
28 + name = user.displayName;
29 + userEmail = user.email;
30 + imageUrl = user.photoURL;
31 + }
32 + }
33 +}
34 +
35 +/// For authenticating user using Google Sign In
36 +/// with Firebase Authentication API.
37 +///
38 +/// Retrieves some general user related information
39 +/// from their Google account for ease of the login process
40 +Future<User?> signInWithGoogle() async {
41 + await Firebase.initializeApp();
42 +
43 + User? user;
44 +
45 + if (kIsWeb) {
46 + GoogleAuthProvider authProvider = GoogleAuthProvider();
47 +
48 + try {
49 + final UserCredential userCredential =
50 + await _auth.signInWithPopup(authProvider);
51 +
52 + user = userCredential.user;
53 + } catch (e) {
54 + print(e);
55 + }
56 + } else {
57 + final GoogleSignIn googleSignIn = GoogleSignIn();
58 +
59 + final GoogleSignInAccount? googleSignInAccount =
60 + await googleSignIn.signIn();
61 +
62 + if (googleSignInAccount != null) {
63 + final GoogleSignInAuthentication googleSignInAuthentication =
64 + await googleSignInAccount.authentication;
65 +
66 + final AuthCredential credential = GoogleAuthProvider.credential(
67 + accessToken: googleSignInAuthentication.accessToken,
68 + idToken: googleSignInAuthentication.idToken,
69 + );
70 +
71 + try {
72 + final UserCredential userCredential =
73 + await _auth.signInWithCredential(credential);
74 +
75 + user = userCredential.user;
76 + } on FirebaseAuthException catch (e) {
77 + if (e.code == 'account-exists-with-different-credential') {
78 + print('The account already exists with a different credential.');
79 + } else if (e.code == 'invalid-credential') {
80 + print('Error occurred while accessing credentials. Try again.');
81 + }
82 + } catch (e) {
83 + print(e);
84 + }
85 + }
86 + }
87 +
88 + if (user != null) {
89 + uid = user.uid;
90 + name = user.displayName;
91 + userEmail = user.email;
92 + imageUrl = user.photoURL;
93 +
94 + SharedPreferences prefs = await SharedPreferences.getInstance();
95 + prefs.setBool('auth', true);
96 + }
97 +
98 + return user;
99 +}
100 +
101 +Future<User?> registerWithEmailPassword(String email, String password) async {
102 + await Firebase.initializeApp();
103 + User? user;
104 +
105 + try {
106 + UserCredential userCredential = await _auth.createUserWithEmailAndPassword(
107 + email: email,
108 + password: password,
109 + );
110 +
111 + user = userCredential.user;
112 +
113 + if (user != null) {
114 + uid = user.uid;
115 + userEmail = user.email;
116 + }
117 + } on FirebaseAuthException catch (e) {
118 + if (e.code == 'weak-password') {
119 + print('The password provided is too weak.');
120 + } else if (e.code == 'email-already-in-use') {
121 + print('The account already exists for that email.');
122 + }
123 + } catch (e) {
124 + print(e);
125 + }
126 +
127 + return user;
128 +}
129 +
130 +Future<User?> signInWithEmailPassword(String email, String password) async {
131 + await Firebase.initializeApp();
132 + User? user;
133 +
134 + try {
135 + UserCredential userCredential = await _auth.signInWithEmailAndPassword(
136 + email: email,
137 + password: password,
138 + );
139 + user = userCredential.user;
140 +
141 + if (user != null) {
142 + uid = user.uid;
143 + userEmail = user.email;
144 +
145 + SharedPreferences prefs = await SharedPreferences.getInstance();
146 + await prefs.setBool('auth', true);
147 + }
148 + } on FirebaseAuthException catch (e) {
149 + if (e.code == 'user-not-found') {
150 + print('No user found for that email.');
151 + } else if (e.code == 'wrong-password') {
152 + print('Wrong password provided.');
153 + }
154 + }
155 +
156 + return user;
157 +}
158 +
159 +Future<String> signOut() async {
160 + await _auth.signOut();
161 +
162 + SharedPreferences prefs = await SharedPreferences.getInstance();
163 + prefs.setBool('auth', false);
164 +
165 + uid = null;
166 + userEmail = null;
167 +
168 + return 'User signed out';
169 +}
170 +
171 +/// For signing out of their Google account
172 +void signOutGoogle() async {
173 + await googleSignIn.signOut();
174 + await _auth.signOut();
175 +
176 + SharedPreferences prefs = await SharedPreferences.getInstance();
177 + prefs.setBool('auth', false);
178 +
179 + uid = null;
180 + name = null;
181 + userEmail = null;
182 + imageUrl = null;
183 +
184 + print("User signed out of Google account");
185 +}
1 +import 'package:flutter/material.dart';
2 +
3 +var lightThemeData = ThemeData(
4 + primarySwatch: Colors.blueGrey,
5 + backgroundColor: Colors.white,
6 + cardColor: Colors.blueGrey[50],
7 + primaryTextTheme: TextTheme(
8 + button: TextStyle(
9 + color: Colors.blueGrey,
10 + decorationColor: Colors.blueGrey[300],
11 + ),
12 + subtitle2: TextStyle(
13 + color: Colors.blueGrey[900],
14 + ),
15 + subtitle1: TextStyle(
16 + color: Colors.black,
17 + ),
18 + headline1: TextStyle(color: Colors.blueGrey[800]),
19 + ),
20 + bottomAppBarColor: Colors.blueGrey[900],
21 + iconTheme: IconThemeData(color: Colors.blueGrey),
22 + brightness: Brightness.light,
23 +);
24 +
25 +var darkThemeData = ThemeData(
26 + primarySwatch: Colors.blueGrey,
27 + backgroundColor: Colors.blueGrey[900],
28 + cardColor: Colors.black,
29 + primaryTextTheme: TextTheme(
30 + button: TextStyle(
31 + color: Colors.blueGrey[200],
32 + decorationColor: Colors.blueGrey[50],
33 + ),
34 + subtitle2: TextStyle(
35 + color: Colors.white,
36 + ),
37 + subtitle1: TextStyle(
38 + color: Colors.blueGrey[300],
39 + ),
40 + headline1: TextStyle(
41 + color: Colors.white70,
42 + ),
43 + ),
44 + bottomAppBarColor: Colors.black,
45 + iconTheme: IconThemeData(color: Colors.blueGrey[200]),
46 + brightness: Brightness.dark,
47 +);
1 +import 'package:like/screens/home_page.dart';
2 +//import 'package:like/utils/authentication.dart';
3 +import 'package:flutter/material.dart';
4 +
5 +import 'google_sign_in_button.dart';
6 +import 'dart:convert';
7 +import 'dart:typed_data';
8 +import 'package:cookie_jar/cookie_jar.dart';
9 +import 'package:dio/dio.dart';
10 +import 'package:flutter/material.dart';
11 +
12 +
13 +import 'package:like/models/user.dart';
14 +import 'package:provider/provider.dart';
15 +import '../../env.dart';
16 +
17 +class AuthDialog extends StatefulWidget {
18 + @override
19 + _AuthDialogState createState() => _AuthDialogState();
20 +}
21 +
22 +class _AuthDialogState extends State<AuthDialog> {
23 + late TextEditingController textControllerEmail;
24 + late FocusNode textFocusNodeEmail;
25 + bool _isEditingEmail = false;
26 +
27 + late TextEditingController textControllerPassword;
28 + late FocusNode textFocusNodePassword;
29 + bool _isEditingPassword = false;
30 +
31 + bool _isRegistering = false;
32 + bool _isLoggingIn = false;
33 + final _formKey = GlobalKey<FormState>();
34 + String? loginStatus;
35 + Color loginStringColor = Colors.green;
36 + var exist = false;
37 + var validPassword = false;
38 +
39 + String? _validateEmail(String value) {
40 + value = value.trim();
41 +
42 + if (textControllerEmail.text.isNotEmpty) {
43 + if (value.isEmpty) {
44 + return 'Email can\'t be empty';
45 + } else if (!value.contains(RegExp(
46 + r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+"))) {
47 + return 'Enter a correct email address';
48 + }
49 + }
50 +
51 + return null;
52 + }
53 +
54 + String? _validatePassword(String value) {
55 + value = value.trim();
56 +
57 + if (textControllerEmail.text.isNotEmpty) {
58 + if (value.isEmpty) {
59 + return 'Password can\'t be empty';
60 + } else if (value.length < 6) {
61 + return 'Length of password should be greater than 6';
62 + }
63 + }
64 +
65 + return null;
66 + }
67 +
68 + @override
69 + void initState() {
70 + textControllerEmail = TextEditingController();
71 + textControllerPassword = TextEditingController();
72 + textControllerEmail.text = '';
73 + textControllerPassword.text = '';
74 + textFocusNodeEmail = FocusNode();
75 + textFocusNodePassword = FocusNode();
76 + super.initState();
77 + }
78 +
79 + @override
80 + Widget build(BuildContext context) {
81 + return Dialog(
82 + backgroundColor: Theme.of(context).backgroundColor,
83 + shape: RoundedRectangleBorder(
84 + borderRadius: BorderRadius.circular(8.0),
85 + ),
86 + child: SingleChildScrollView(
87 + child: Padding(
88 + padding: const EdgeInsets.all(16.0),
89 + child: Container(
90 + width: 400,
91 + color: Theme.of(context).backgroundColor,
92 + child: Column(
93 + crossAxisAlignment: CrossAxisAlignment.start,
94 + mainAxisSize: MainAxisSize.min,
95 + children: [
96 + Center(
97 + child: Text(
98 + 'EXPLORE',
99 + style: TextStyle(
100 + color: Theme.of(context).textTheme.headline1!.color,
101 + fontSize: 24,
102 + fontFamily: 'Montserrat',
103 + fontWeight: FontWeight.bold,
104 + letterSpacing: 3,
105 + ),
106 + ),
107 + ),
108 + SizedBox(height: 30),
109 + Padding(
110 + padding: const EdgeInsets.only(
111 + left: 20.0,
112 + bottom: 8,
113 + ),
114 + child: Text(
115 + 'Email address',
116 + textAlign: TextAlign.left,
117 + style: TextStyle(
118 + color: Theme.of(context).textTheme.subtitle2!.color,
119 + fontSize: 18,
120 + // fontFamily: 'Montserrat',
121 + fontWeight: FontWeight.bold,
122 + // letterSpacing: 3,
123 + ),
124 + ),
125 + ),
126 + Padding(
127 + padding: const EdgeInsets.only(
128 + left: 20.0,
129 + right: 20,
130 + ),
131 + child: TextField(
132 + focusNode: textFocusNodeEmail,
133 + keyboardType: TextInputType.emailAddress,
134 + textInputAction: TextInputAction.next,
135 + controller: textControllerEmail,
136 + autofocus: false,
137 + onChanged: (value) {
138 + setState(() {
139 + _isEditingEmail = true;
140 + });
141 + },
142 + onSubmitted: (value) {
143 + textFocusNodeEmail.unfocus();
144 + FocusScope.of(context)
145 + .requestFocus(textFocusNodePassword);
146 + },
147 + style: TextStyle(color: Colors.black),
148 + decoration: InputDecoration(
149 + border: new OutlineInputBorder(
150 + borderRadius: BorderRadius.circular(10),
151 + borderSide: BorderSide(
152 + color: Colors.blueGrey[800]!,
153 + width: 3,
154 + ),
155 + ),
156 + filled: true,
157 + hintStyle: new TextStyle(
158 + color: Colors.blueGrey[300],
159 + ),
160 + hintText: "Email",
161 + fillColor: Colors.white,
162 + errorText: _isEditingEmail
163 + ? _validateEmail(textControllerEmail.text)
164 + : null,
165 + errorStyle: TextStyle(
166 + fontSize: 12,
167 + color: Colors.redAccent,
168 + ),
169 + ),
170 + ),
171 + ),
172 + SizedBox(height: 20),
173 + Padding(
174 + padding: const EdgeInsets.only(
175 + left: 20.0,
176 + bottom: 8,
177 + ),
178 + child: Text(
179 + 'Password',
180 + textAlign: TextAlign.left,
181 + style: TextStyle(
182 + color: Theme.of(context).textTheme.subtitle2!.color,
183 + fontSize: 18,
184 + fontWeight: FontWeight.bold,
185 + // letterSpacing: 3,
186 + ),
187 + ),
188 + ),
189 + Padding(
190 + padding: const EdgeInsets.only(
191 + left: 20.0,
192 + right: 20,
193 + ),
194 + child: TextField(
195 + focusNode: textFocusNodePassword,
196 + keyboardType: TextInputType.text,
197 + textInputAction: TextInputAction.done,
198 + controller: textControllerPassword,
199 + obscureText: true,
200 + autofocus: false,
201 + onChanged: (value) {
202 + setState(() {
203 + _isEditingPassword = true;
204 + });
205 + },
206 + onSubmitted: (value) {
207 + textFocusNodePassword.unfocus();
208 + FocusScope.of(context)
209 + .requestFocus(textFocusNodePassword);
210 + },
211 + style: TextStyle(color: Colors.black),
212 + decoration: InputDecoration(
213 + border: new OutlineInputBorder(
214 + borderRadius: BorderRadius.circular(10),
215 + borderSide: BorderSide(
216 + color: Colors.blueGrey[800]!,
217 + width: 3,
218 + ),
219 + ),
220 + filled: true,
221 + hintStyle: new TextStyle(
222 + color: Colors.blueGrey[300],
223 + ),
224 + hintText: "Password",
225 + fillColor: Colors.white,
226 + errorText: _isEditingPassword
227 + ? _validatePassword(textControllerPassword.text)
228 + : null,
229 + errorStyle: TextStyle(
230 + fontSize: 12,
231 + color: Colors.redAccent,
232 + ),
233 + ),
234 + ),
235 + ),
236 + Padding(
237 + padding: const EdgeInsets.all(20.0),
238 + child: Row(
239 + mainAxisSize: MainAxisSize.max,
240 + mainAxisAlignment: MainAxisAlignment.spaceAround,
241 + children: [
242 + Flexible(
243 + flex: 1,
244 + child: Container(
245 + width: double.maxFinite,
246 + child: TextButton(
247 + style: TextButton.styleFrom(
248 + primary: Colors.blueGrey.shade800,
249 + shape: RoundedRectangleBorder(
250 + borderRadius: BorderRadius.circular(15.0),
251 + ),
252 + ),
253 + onPressed: () async {
254 + if(textControllerEmail.text.isEmpty){}
255 +
256 + if(textControllerEmail.text.isEmpty){
257 + if (await loginWithlocalAndPostSuccess(textControllerEmail.text, textControllerPassword.text)) {
258 + //cookies test
259 + //로그인 정보 서버로 보내고 확인받고 user model에 저장후 넘기기.
260 + Navigator.of(context).pushNamedAndRemoveUntil(
261 + '/home', (Route<dynamic> route) => false);
262 + }
263 + } else{
264 + print('Error');
265 + }
266 + },
267 + child: Padding(
268 + padding: EdgeInsets.only(
269 + top: 15.0,
270 + bottom: 15.0,
271 + ),
272 + child: _isLoggingIn
273 + ? SizedBox(
274 + height: 16,
275 + width: 16,
276 + child: CircularProgressIndicator(
277 + strokeWidth: 2,
278 + valueColor:
279 + new AlwaysStoppedAnimation<Color>(
280 + Colors.white,
281 + ),
282 + ),
283 + )
284 + : Text(
285 + 'Log in',
286 + style: TextStyle(
287 + fontSize: 14,
288 + color: Colors.white,
289 + ),
290 + ),
291 + ),
292 + ),
293 + ),
294 + ),
295 + SizedBox(width: 20),
296 + Flexible(
297 + flex: 1,
298 + child: Container(
299 + width: double.maxFinite,
300 + child: TextButton(
301 + style: TextButton.styleFrom(
302 + primary: Colors.blueGrey.shade800,
303 + shape: RoundedRectangleBorder(
304 + borderRadius: BorderRadius.circular(15),
305 + ),
306 + ),
307 + onPressed: () async {
308 + setState(() {
309 + _isRegistering = true;
310 + });
311 +
312 +
313 +
314 + setState(() {
315 + _isRegistering = false;
316 + });
317 + },
318 + child: Padding(
319 + padding: EdgeInsets.only(
320 + top: 15.0,
321 + bottom: 15.0,
322 + ),
323 + child: _isRegistering
324 + ? SizedBox(
325 + height: 16,
326 + width: 16,
327 + child: CircularProgressIndicator(
328 + strokeWidth: 2,
329 + valueColor:
330 + new AlwaysStoppedAnimation<Color>(
331 + Colors.white,
332 + ),
333 + ),
334 + )
335 + : Text(
336 + 'Sign up',
337 + style: TextStyle(
338 + fontSize: 14,
339 + color: Colors.white,
340 + ),
341 + ),
342 + ),
343 + ),
344 + ),
345 + ),
346 + ],
347 + ),
348 + ),
349 + loginStatus != null
350 + ? Center(
351 + child: Padding(
352 + padding: const EdgeInsets.only(
353 + bottom: 20.0,
354 + ),
355 + child: Text(
356 + loginStatus!,
357 + style: TextStyle(
358 + color: loginStringColor,
359 + fontSize: 14,
360 + // letterSpacing: 3,
361 + ),
362 + ),
363 + ),
364 + )
365 + : Container(),
366 + Padding(
367 + padding: const EdgeInsets.only(
368 + left: 40.0,
369 + right: 40.0,
370 + ),
371 + child: Container(
372 + height: 1,
373 + width: double.maxFinite,
374 + color: Colors.blueGrey[200],
375 + ),
376 + ),
377 + SizedBox(height: 30),
378 + Center(child: GoogleButton()),
379 + SizedBox(height: 30),
380 + Padding(
381 + padding: const EdgeInsets.all(8.0),
382 + child: Text(
383 + 'By proceeding, you agree to our Terms of Use and confirm you have read our Privacy Policy.',
384 + maxLines: 2,
385 + style: TextStyle(
386 + color: Theme.of(context).textTheme.subtitle2!.color,
387 + fontSize: 14,
388 + fontWeight: FontWeight.w300,
389 + // letterSpacing: 3,
390 + ),
391 + ),
392 + ),
393 + ],
394 + ),
395 + ),
396 + ),
397 + ),
398 + );
399 + }
400 +}
401 + processingPet(data) {
402 + List<Uint8List> images = [];
403 + for (int j = 0; j < data['image'].length; j++) {
404 + var temp = new List<int>.from(data['image'][j]['data']);
405 + images.add(Uint8List.fromList(temp));
406 + }
407 + var pet = {
408 + "name": data['name'],
409 + "_id": data['_id'],
410 + "ownerId": data['ownerId'],
411 + "species": data['species'],
412 + "birth": data['birth']?.substring(0, 10),
413 + "weight": data['weight']?.toString(),
414 + "image": images,
415 + "petType": data['petType']
416 + };
417 + return pet;
418 + }
419 +
420 + loginWithlocalAndPostSuccess(String id, String password) async {
421 + var response = await dio.post("/api/auth/signin/local",
422 + data: {'email': id, 'password': password});
423 + if (response.statusCode == 200) {
424 + //context.read<User>().update(response.data);
425 + return true;
426 + }
427 + }
...\ No newline at end of file ...\ No newline at end of file
1 +import 'package:like/widgets/bottom_bar_column.dart';
2 +import 'package:like/widgets/info_text.dart';
3 +import 'package:like/widgets/responsive.dart';
4 +
5 +import 'package:flutter/material.dart';
6 +
7 +class BottomBar extends StatelessWidget {
8 + @override
9 + Widget build(BuildContext context) {
10 + return Container(
11 + padding: EdgeInsets.all(30),
12 + color: Theme.of(context).bottomAppBarColor,
13 + child: ResponsiveWidget.isSmallScreen(context)
14 + ? Column(
15 + children: [
16 + Row(
17 + mainAxisSize: MainAxisSize.max,
18 + mainAxisAlignment: MainAxisAlignment.spaceAround,
19 + children: [
20 + BottomBarColumn(
21 + heading: 'ABOUT',
22 + s1: 'Contact Us',
23 + s2: 'About Us',
24 + s3: 'Careers',
25 + ),
26 + BottomBarColumn(
27 + heading: 'HELP',
28 + s1: 'Payment',
29 + s2: 'Cancellation',
30 + s3: 'FAQ',
31 + ),
32 + BottomBarColumn(
33 + heading: 'SOCIAL',
34 + s1: 'Twitter',
35 + s2: 'Facebook',
36 + s3: 'YouTube',
37 + ),
38 + ],
39 + ),
40 + Container(
41 + color: Colors.blueGrey,
42 + width: double.maxFinite,
43 + height: 1,
44 + ),
45 + SizedBox(height: 20),
46 + InfoText(
47 + type: 'Email',
48 + text: 'explore@gmail.com',
49 + ),
50 + SizedBox(height: 5),
51 + InfoText(
52 + type: 'Address',
53 + text: '128, Trymore Road, Delft, MN - 56124',
54 + ),
55 + SizedBox(height: 20),
56 + Container(
57 + color: Colors.blueGrey,
58 + width: double.maxFinite,
59 + height: 1,
60 + ),
61 + SizedBox(height: 20),
62 + Text(
63 + 'Copyright © 2020 | EXPLORE',
64 + style: TextStyle(
65 + color: Colors.blueGrey[300],
66 + fontSize: 14,
67 + ),
68 + ),
69 + ],
70 + )
71 + : Column(
72 + children: [
73 + Row(
74 + mainAxisSize: MainAxisSize.max,
75 + mainAxisAlignment: MainAxisAlignment.spaceAround,
76 + children: [
77 + BottomBarColumn(
78 + heading: 'ABOUT',
79 + s1: 'Contact Us',
80 + s2: 'About Us',
81 + s3: 'Careers',
82 + ),
83 + BottomBarColumn(
84 + heading: 'HELP',
85 + s1: 'Payment',
86 + s2: 'Cancellation',
87 + s3: 'FAQ',
88 + ),
89 + BottomBarColumn(
90 + heading: 'SOCIAL',
91 + s1: 'Twitter',
92 + s2: 'Facebook',
93 + s3: 'YouTube',
94 + ),
95 + Container(
96 + color: Colors.blueGrey,
97 + width: 2,
98 + height: 150,
99 + ),
100 + Column(
101 + crossAxisAlignment: CrossAxisAlignment.start,
102 + children: [
103 + InfoText(
104 + type: 'Email',
105 + text: 'explore@gmail.com',
106 + ),
107 + SizedBox(height: 5),
108 + InfoText(
109 + type: 'Address',
110 + text: '128, Trymore Road, Delft, MN - 56124',
111 + )
112 + ],
113 + ),
114 + ],
115 + ),
116 + Padding(
117 + padding: const EdgeInsets.all(8.0),
118 + child: Container(
119 + color: Colors.blueGrey,
120 + width: double.maxFinite,
121 + height: 1,
122 + ),
123 + ),
124 + ],
125 + ),
126 + );
127 + }
128 +}
1 +import 'package:flutter/material.dart';
2 +
3 +class BottomBarColumn extends StatelessWidget {
4 + final String heading;
5 + final String s1;
6 + final String s2;
7 + final String s3;
8 +
9 + BottomBarColumn({
10 + required this.heading,
11 + required this.s1,
12 + required this.s2,
13 + required this.s3,
14 + });
15 +
16 + @override
17 + Widget build(BuildContext context) {
18 + return Padding(
19 + padding: EdgeInsets.only(bottom: 20.0),
20 + child: Column(
21 + crossAxisAlignment: CrossAxisAlignment.start,
22 + children: [
23 + Text(
24 + heading,
25 + style: TextStyle(
26 + color: Colors.blueGrey[300],
27 + fontSize: 18,
28 + fontWeight: FontWeight.w500,
29 + ),
30 + ),
31 + SizedBox(
32 + height: 10,
33 + ),
34 + Text(
35 + s1,
36 + style: TextStyle(
37 + color: Colors.blueGrey[100],
38 + fontSize: 14,
39 + ),
40 + ),
41 + SizedBox(height: 5),
42 + Text(
43 + s2,
44 + style: TextStyle(
45 + color: Colors.blueGrey[100],
46 + fontSize: 14,
47 + ),
48 + ),
49 + SizedBox(height: 5),
50 + Text(
51 + s3,
52 + style: TextStyle(
53 + color: Colors.blueGrey[100],
54 + fontSize: 14,
55 + ),
56 + ),
57 + ],
58 + ),
59 + );
60 + }
61 +}
1 +import 'package:carousel_slider/carousel_slider.dart';
2 +import 'package:like/widgets/responsive.dart';
3 +import 'package:flutter/material.dart';
4 +
5 +class DestinationCarousel extends StatefulWidget {
6 + @override
7 + _DestinationCarouselState createState() => _DestinationCarouselState();
8 +}
9 +
10 +class _DestinationCarouselState extends State<DestinationCarousel> {
11 + final String imagePath = 'assets/images/';
12 +
13 + final CarouselController _controller = CarouselController();
14 +
15 + List _isHovering = [false, false, false, false, false, false, false];
16 + List _isSelected = [true, false, false, false, false, false, false];
17 +
18 + int _current = 0;
19 +
20 + final List<String> images = [
21 + 'assets/images/asia.jpg',
22 + 'assets/images/africa.jpg',
23 + 'assets/images/europe.jpg',
24 + 'assets/images/south_america.jpg',
25 + 'assets/images/australia.jpg',
26 + 'assets/images/antarctica.jpg',
27 + ];
28 +
29 + final List<String> places = [
30 + 'ASIA',
31 + 'AFRICA',
32 + 'EUROPE',
33 + 'SOUTH AMERICA',
34 + 'AUSTRALIA',
35 + 'ANTARCTICA',
36 + ];
37 +
38 + List<Widget> generateImageTiles(screenSize) {
39 + return images
40 + .map(
41 + (element) => ClipRRect(
42 + borderRadius: BorderRadius.circular(8.0),
43 + child: Image.asset(
44 + element,
45 + fit: BoxFit.cover,
46 + ),
47 + ),
48 + )
49 + .toList();
50 + }
51 +
52 + @override
53 + Widget build(BuildContext context) {
54 + var screenSize = MediaQuery.of(context).size;
55 + var imageSliders = generateImageTiles(screenSize);
56 +
57 + return Stack(
58 + children: [
59 + CarouselSlider(
60 + items: imageSliders,
61 + options: CarouselOptions(
62 + scrollPhysics: ResponsiveWidget.isSmallScreen(context)
63 + ? PageScrollPhysics()
64 + : NeverScrollableScrollPhysics(),
65 + enlargeCenterPage: true,
66 + aspectRatio: 18 / 8,
67 + autoPlay: true,
68 + onPageChanged: (index, reason) {
69 + setState(() {
70 + _current = index;
71 + for (int i = 0; i < imageSliders.length; i++) {
72 + if (i == index) {
73 + _isSelected[i] = true;
74 + } else {
75 + _isSelected[i] = false;
76 + }
77 + }
78 + });
79 + }),
80 + carouselController: _controller,
81 + ),
82 + AspectRatio(
83 + aspectRatio: 18 / 8,
84 + child: Center(
85 + child: Text(
86 + places[_current],
87 + style: TextStyle(
88 + letterSpacing: 8,
89 + fontFamily: 'Electrolize',
90 + fontSize: screenSize.width / 25,
91 + color: Colors.white,
92 + ),
93 + ),
94 + ),
95 + ),
96 + ResponsiveWidget.isSmallScreen(context)
97 + ? Container()
98 + : AspectRatio(
99 + aspectRatio: 17 / 8,
100 + child: Center(
101 + heightFactor: 1,
102 + child: Align(
103 + alignment: Alignment.bottomCenter,
104 + child: Padding(
105 + padding: EdgeInsets.only(
106 + left: screenSize.width / 8,
107 + right: screenSize.width / 8,
108 + ),
109 + child: Card(
110 + elevation: 5,
111 + child: Padding(
112 + padding: EdgeInsets.only(
113 + top: screenSize.height / 50,
114 + bottom: screenSize.height / 50,
115 + ),
116 + child: Row(
117 + mainAxisAlignment: MainAxisAlignment.spaceEvenly,
118 + children: [
119 + for (int i = 0; i < places.length; i++)
120 + Column(
121 + mainAxisSize: MainAxisSize.min,
122 + children: [
123 + InkWell(
124 + splashColor: Colors.blueGrey,
125 + hoverColor: Colors.transparent,
126 + onHover: (value) {
127 + setState(() {
128 + value
129 + ? _isHovering[i] = true
130 + : _isHovering[i] = false;
131 + });
132 + },
133 + onTap: () {
134 + _controller.animateToPage(i);
135 + },
136 + child: Padding(
137 + padding: EdgeInsets.only(
138 + top: screenSize.height / 80,
139 + bottom: screenSize.height / 90),
140 + child: Text(
141 + places[i],
142 + style: TextStyle(
143 + color: _isHovering[i]
144 + ? Theme.of(context)
145 + .primaryTextTheme
146 + .button!
147 + .decorationColor
148 + : Theme.of(context)
149 + .primaryTextTheme
150 + .button!
151 + .decorationColor,
152 + ),
153 + ),
154 + ),
155 + ),
156 + Visibility(
157 + maintainSize: true,
158 + maintainAnimation: true,
159 + maintainState: true,
160 + visible: _isSelected[i],
161 + child: AnimatedOpacity(
162 + duration: Duration(milliseconds: 400),
163 + opacity: _isSelected[i] ? 1 : 0,
164 + child: Container(
165 + height: 5,
166 + decoration: BoxDecoration(
167 + color: Colors.blueGrey,
168 + borderRadius: BorderRadius.all(
169 + Radius.circular(10),
170 + ),
171 + ),
172 + width: screenSize.width / 10,
173 + ),
174 + ),
175 + )
176 + ],
177 + ),
178 + ],
179 + ),
180 + ),
181 + ),
182 + ),
183 + ),
184 + ),
185 + ),
186 + ],
187 + );
188 + }
189 +}
1 +import 'package:like/widgets/responsive.dart';
2 +import 'package:flutter/material.dart';
3 +
4 +class DestinationHeading extends StatelessWidget {
5 + const DestinationHeading({
6 + Key? key,
7 + required this.screenSize,
8 + }) : super(key: key);
9 +
10 + final Size screenSize;
11 +
12 + @override
13 + Widget build(BuildContext context) {
14 + return ResponsiveWidget.isSmallScreen(context)
15 + ? Container(
16 + padding: EdgeInsets.only(
17 + top: screenSize.height / 20,
18 + bottom: screenSize.height / 20,
19 + ),
20 + width: screenSize.width,
21 + // color: Colors.black,
22 + child: Text(
23 + 'Destinations diversity',
24 + textAlign: TextAlign.center,
25 + style: TextStyle(
26 + fontSize: 24,
27 + fontFamily: 'Montserrat',
28 + fontWeight: FontWeight.bold,
29 + ),
30 + ),
31 + )
32 + : Container(
33 + padding: EdgeInsets.only(
34 + top: screenSize.height / 10,
35 + bottom: screenSize.height / 15,
36 + ),
37 + width: screenSize.width,
38 + // color: Colors.black,
39 + child: Text(
40 + 'Destinations diversity',
41 + textAlign: TextAlign.center,
42 + style: TextStyle(
43 + fontSize: 40,
44 + fontFamily: 'Montserrat',
45 + fontWeight: FontWeight.bold,
46 + ),
47 + ),
48 + );
49 + }
50 +}
1 +import 'package:like/screens/home_page.dart';
2 +import 'package:like/utils/authentication.dart';
3 +import 'package:flutter/material.dart';
4 +
5 +import 'auth_dialog.dart';
6 +
7 +class ExploreDrawer extends StatefulWidget {
8 + const ExploreDrawer({
9 + Key? key,
10 + }) : super(key: key);
11 +
12 + @override
13 + _ExploreDrawerState createState() => _ExploreDrawerState();
14 +}
15 +
16 +class _ExploreDrawerState extends State<ExploreDrawer> {
17 + bool _isProcessing = false;
18 + @override
19 + Widget build(BuildContext context) {
20 + return Drawer(
21 + child: Container(
22 + color: Theme.of(context).bottomAppBarColor,
23 + child: Padding(
24 + padding: const EdgeInsets.all(16.0),
25 + child: Column(
26 + crossAxisAlignment: CrossAxisAlignment.start,
27 + mainAxisAlignment: MainAxisAlignment.start,
28 + children: [
29 + userEmail == null
30 + ? Container(
31 + width: double.maxFinite,
32 + child: TextButton(
33 + // color: Colors.black,
34 + // hoverColor: Colors.blueGrey[800],
35 + // highlightColor: Colors.blueGrey[700],
36 + style: TextButton.styleFrom(
37 + primary: Colors.black,
38 + shape: RoundedRectangleBorder(
39 + borderRadius: BorderRadius.circular(15),
40 + ),
41 + ),
42 + onPressed: () {
43 + showDialog(
44 + context: context,
45 + builder: (context) => AuthDialog(),
46 + );
47 + },
48 + // shape: RoundedRectangleBorder(
49 + // borderRadius: BorderRadius.circular(15),
50 + // ),
51 + child: Padding(
52 + padding: EdgeInsets.only(
53 + top: 15.0,
54 + bottom: 15.0,
55 + ),
56 + child: Text(
57 + 'Sign in',
58 + style: TextStyle(
59 + fontSize: 20,
60 + color: Colors.white,
61 + ),
62 + ),
63 + ),
64 + ),
65 + )
66 + : Row(
67 + mainAxisAlignment: MainAxisAlignment.start,
68 + mainAxisSize: MainAxisSize.max,
69 + children: [
70 + CircleAvatar(
71 + radius: 20,
72 + backgroundImage:
73 + imageUrl != null ? NetworkImage(imageUrl!) : null,
74 + child: imageUrl == null
75 + ? Icon(
76 + Icons.account_circle,
77 + size: 40,
78 + )
79 + : Container(),
80 + ),
81 + SizedBox(width: 10),
82 + Text(
83 + name ?? userEmail!,
84 + style: TextStyle(
85 + fontSize: 20,
86 + color: Colors.white70,
87 + ),
88 + )
89 + ],
90 + ),
91 + SizedBox(height: 20),
92 + userEmail != null
93 + ? Container(
94 + width: double.maxFinite,
95 + child: TextButton(
96 + // color: Colors.black,
97 + // hoverColor: Colors.blueGrey[800],
98 + // highlightColor: Colors.blueGrey[700],
99 + style: TextButton.styleFrom(
100 + primary: Colors.black,
101 + shape: RoundedRectangleBorder(
102 + borderRadius: BorderRadius.circular(15),
103 + ),
104 + ),
105 + onPressed: _isProcessing
106 + ? null
107 + : () async {
108 + setState(() {
109 + _isProcessing = true;
110 + });
111 + await signOut().then((result) {
112 + print(result);
113 + Navigator.of(context).pushReplacement(
114 + MaterialPageRoute(
115 + fullscreenDialog: true,
116 + builder: (context) => HomePage(),
117 + ),
118 + );
119 + }).catchError((error) {
120 + print('Sign Out Error: $error');
121 + });
122 + setState(() {
123 + _isProcessing = false;
124 + });
125 + },
126 + // shape: RoundedRectangleBorder(
127 + // borderRadius: BorderRadius.circular(15),
128 + // ),
129 + child: Padding(
130 + padding: EdgeInsets.only(
131 + top: 15.0,
132 + bottom: 15.0,
133 + ),
134 + child: _isProcessing
135 + ? CircularProgressIndicator()
136 + : Text(
137 + 'Sign out',
138 + style: TextStyle(
139 + fontSize: 20,
140 + color: Colors.white,
141 + ),
142 + ),
143 + ),
144 + ),
145 + )
146 + : Container(),
147 + userEmail != null ? SizedBox(height: 20) : Container(),
148 + InkWell(
149 + onTap: () {},
150 + child: Text(
151 + 'Discover',
152 + style: TextStyle(color: Colors.white, fontSize: 22),
153 + ),
154 + ),
155 + Padding(
156 + padding: const EdgeInsets.only(top: 5.0, bottom: 5.0),
157 + child: Divider(
158 + color: Colors.blueGrey[400],
159 + thickness: 2,
160 + ),
161 + ),
162 + InkWell(
163 + onTap: () {},
164 + child: Text(
165 + 'Contact Us',
166 + style: TextStyle(color: Colors.white, fontSize: 22),
167 + ),
168 + ),
169 + Expanded(
170 + child: Align(
171 + alignment: Alignment.bottomCenter,
172 + child: Text(
173 + 'Copyright © 2020 | EXPLORE',
174 + style: TextStyle(
175 + color: Colors.blueGrey[300],
176 + fontSize: 14,
177 + ),
178 + ),
179 + ),
180 + )
181 + ],
182 + ),
183 + ),
184 + ),
185 + );
186 + }
187 +}
1 +import 'package:like/widgets/responsive.dart';
2 +import 'package:flutter/material.dart';
3 +
4 +class FeaturedHeading extends StatelessWidget {
5 + const FeaturedHeading({
6 + Key? key,
7 + required this.screenSize,
8 + }) : super(key: key);
9 +
10 + final Size screenSize;
11 +
12 + @override
13 + Widget build(BuildContext context) {
14 + return Padding(
15 + padding: EdgeInsets.only(
16 + top: screenSize.height * 0.06,
17 + left: screenSize.width / 15,
18 + right: screenSize.width / 15,
19 + ),
20 + child: ResponsiveWidget.isSmallScreen(context)
21 + ? Column(
22 + crossAxisAlignment: CrossAxisAlignment.start,
23 + mainAxisAlignment: MainAxisAlignment.start,
24 + children: [
25 + Row(),
26 + Text(
27 + 'Featured',
28 + style: TextStyle(
29 + fontSize: 24,
30 + fontFamily: 'Montserrat',
31 + fontWeight: FontWeight.bold,
32 + ),
33 + ),
34 + SizedBox(height: 5),
35 + Text(
36 + 'Unique wildlife tours & destinations',
37 + textAlign: TextAlign.end,
38 + style: Theme.of(context).primaryTextTheme.subtitle1,
39 + ),
40 + SizedBox(height: 10),
41 + ],
42 + )
43 + : Row(
44 + mainAxisSize: MainAxisSize.max,
45 + mainAxisAlignment: MainAxisAlignment.start,
46 + children: [
47 + Text(
48 + 'Featured',
49 + style: TextStyle(
50 + fontSize: 40,
51 + fontFamily: 'Montserrat',
52 + fontWeight: FontWeight.bold,
53 + ),
54 + ),
55 + Expanded(
56 + child: Text(
57 + 'Unique wildlife tours & destinations',
58 + textAlign: TextAlign.end,
59 + style: Theme.of(context).primaryTextTheme.subtitle1,
60 + ),
61 + ),
62 + ],
63 + ),
64 + );
65 + }
66 +}
1 +import 'package:like/widgets/responsive.dart';
2 +import 'package:flutter/material.dart';
3 +
4 +class FeaturedTiles extends StatelessWidget {
5 + FeaturedTiles({
6 + Key? key,
7 + required this.screenSize,
8 + }) : super(key: key);
9 +
10 + final Size screenSize;
11 +
12 + final List<String> assets = [
13 + 'assets/images/trekking.jpg',
14 + 'assets/images/animals.jpg',
15 + 'assets/images/photography.jpeg',
16 + ];
17 +
18 + final List<String> title = ['Trekking', 'Animals', 'Photography'];
19 +
20 + @override
21 + Widget build(BuildContext context) {
22 + return ResponsiveWidget.isSmallScreen(context)
23 + ? Padding(
24 + padding: EdgeInsets.only(top: screenSize.height / 50),
25 + child: SingleChildScrollView(
26 + scrollDirection: Axis.horizontal,
27 + child: Row(
28 + mainAxisAlignment: MainAxisAlignment.start,
29 + children: [
30 + SizedBox(width: screenSize.width / 15),
31 + ...Iterable<int>.generate(assets.length).map(
32 + (int pageIndex) => Row(
33 + children: [
34 + Column(
35 + crossAxisAlignment: CrossAxisAlignment.start,
36 + children: [
37 + SizedBox(
38 + height: screenSize.width / 2.5,
39 + width: screenSize.width / 1.5,
40 + child: ClipRRect(
41 + borderRadius: BorderRadius.circular(5.0),
42 + child: Image.asset(
43 + assets[pageIndex],
44 + fit: BoxFit.cover,
45 + ),
46 + ),
47 + ),
48 + Padding(
49 + padding: EdgeInsets.only(
50 + top: screenSize.height / 70,
51 + ),
52 + child: Text(
53 + title[pageIndex],
54 + style: TextStyle(
55 + fontSize: 16,
56 + fontFamily: 'Montserrat',
57 + fontWeight: FontWeight.w500,
58 + color: Theme.of(context)
59 + .primaryTextTheme
60 + .subtitle1!
61 + .color,
62 + ),
63 + ),
64 + ),
65 + ],
66 + ),
67 + SizedBox(width: screenSize.width / 15),
68 + ],
69 + ),
70 + ),
71 + ],
72 + ),
73 + ),
74 + )
75 + : Padding(
76 + padding: EdgeInsets.only(
77 + top: screenSize.height * 0.06,
78 + left: screenSize.width / 15,
79 + right: screenSize.width / 15,
80 + ),
81 + child: Row(
82 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
83 + children: [
84 + ...Iterable<int>.generate(assets.length).map(
85 + (int pageIndex) => Column(
86 + children: [
87 + SizedBox(
88 + height: screenSize.width / 6,
89 + width: screenSize.width / 3.8,
90 + child: ClipRRect(
91 + borderRadius: BorderRadius.circular(5.0),
92 + child: Image.asset(
93 + assets[pageIndex],
94 + fit: BoxFit.cover,
95 + ),
96 + ),
97 + ),
98 + Padding(
99 + padding: EdgeInsets.only(
100 + top: screenSize.height / 70,
101 + ),
102 + child: Text(
103 + title[pageIndex],
104 + style: TextStyle(
105 + fontSize: 16,
106 + fontFamily: 'Montserrat',
107 + fontWeight: FontWeight.w500,
108 + color: Theme.of(context)
109 + .primaryTextTheme
110 + .subtitle1!
111 + .color,
112 + ),
113 + ),
114 + ),
115 + ],
116 + ),
117 + ),
118 + ],
119 + ),
120 + );
121 + }
122 +}
1 +import 'package:like/widgets/responsive.dart';
2 +import 'package:flutter/material.dart';
3 +
4 +class FloatingQuickAccessBar extends StatefulWidget {
5 + const FloatingQuickAccessBar({
6 + Key? key,
7 + required this.screenSize,
8 + }) : super(key: key);
9 +
10 + final Size screenSize;
11 +
12 + @override
13 + _FloatingQuickAccessBarState createState() => _FloatingQuickAccessBarState();
14 +}
15 +
16 +class _FloatingQuickAccessBarState extends State<FloatingQuickAccessBar> {
17 + List _isHovering = [false, false, false, false];
18 + List<Widget> rowElements = [];
19 +
20 + List<String> items = ['Destination', 'Dates', 'People', 'Experience'];
21 + List<IconData> icons = [
22 + Icons.location_on,
23 + Icons.date_range,
24 + Icons.people,
25 + Icons.wb_sunny
26 + ];
27 +
28 + List<Widget> generateRowElements() {
29 + rowElements.clear();
30 + for (int i = 0; i < items.length; i++) {
31 + Widget elementTile = InkWell(
32 + splashColor: Colors.transparent,
33 + hoverColor: Colors.transparent,
34 + onHover: (value) {
35 + setState(() {
36 + value ? _isHovering[i] = true : _isHovering[i] = false;
37 + });
38 + },
39 + onTap: () {},
40 + child: Text(
41 + items[i],
42 + style: TextStyle(
43 + color: _isHovering[i]
44 + ? Theme.of(context).primaryTextTheme.button!.decorationColor
45 + : Theme.of(context).primaryTextTheme.button!.decorationColor,
46 + ),
47 + ),
48 + );
49 + Widget spacer = SizedBox(
50 + height: widget.screenSize.height / 20,
51 + child: VerticalDivider(
52 + width: 1,
53 + color: Colors.blueGrey[100],
54 + thickness: 1,
55 + ),
56 + );
57 + rowElements.add(elementTile);
58 + if (i < items.length - 1) {
59 + rowElements.add(spacer);
60 + }
61 + }
62 +
63 + return rowElements;
64 + }
65 +
66 + @override
67 + Widget build(BuildContext context) {
68 + return Center(
69 + heightFactor: 1,
70 + child: Padding(
71 + padding: EdgeInsets.only(
72 + top: widget.screenSize.height * 0.40,
73 + left: ResponsiveWidget.isSmallScreen(context)
74 + ? widget.screenSize.width / 12
75 + : widget.screenSize.width / 5,
76 + right: ResponsiveWidget.isSmallScreen(context)
77 + ? widget.screenSize.width / 12
78 + : widget.screenSize.width / 5,
79 + ),
80 + child: ResponsiveWidget.isSmallScreen(context)
81 + ? Column(
82 + children: [
83 + ...Iterable<int>.generate(items.length).map(
84 + (int pageIndex) => Padding(
85 + padding:
86 + EdgeInsets.only(top: widget.screenSize.height / 80),
87 + child: Card(
88 + color: Theme.of(context).cardColor,
89 + elevation: 4,
90 + child: Padding(
91 + padding: EdgeInsets.only(
92 + top: widget.screenSize.height / 45,
93 + bottom: widget.screenSize.height / 45,
94 + left: widget.screenSize.width / 20),
95 + child: Row(
96 + children: [
97 + Icon(
98 + icons[pageIndex],
99 + color: Theme.of(context).iconTheme.color,
100 + ),
101 + SizedBox(width: widget.screenSize.width / 20),
102 + InkWell(
103 + splashColor: Colors.transparent,
104 + hoverColor: Colors.transparent,
105 + onTap: () {},
106 + child: Text(
107 + items[pageIndex],
108 + style: TextStyle(
109 + color: Theme.of(context)
110 + .primaryTextTheme
111 + .button!
112 + .color,
113 + fontSize: 16),
114 + ),
115 + ),
116 + ],
117 + ),
118 + ),
119 + ),
120 + ),
121 + ),
122 + ],
123 + )
124 + : Card(
125 + elevation: 5,
126 + child: Padding(
127 + padding: EdgeInsets.only(
128 + top: widget.screenSize.height / 50,
129 + bottom: widget.screenSize.height / 50,
130 + ),
131 + child: Row(
132 + mainAxisAlignment: MainAxisAlignment.spaceEvenly,
133 + children: generateRowElements(),
134 + ),
135 + ),
136 + ),
137 + ),
138 + );
139 + }
140 +}
1 +import 'package:like/screens/home_page.dart';
2 +//import 'package:like/utils/authentication.dart';
3 +import 'package:flutter/material.dart';
4 +
5 +class GoogleButton extends StatefulWidget {
6 + @override
7 + _GoogleButtonState createState() => _GoogleButtonState();
8 +}
9 +
10 +class _GoogleButtonState extends State<GoogleButton> {
11 + bool _isProcessing = false;
12 +
13 + @override
14 + Widget build(BuildContext context) {
15 + return DecoratedBox(
16 + decoration: ShapeDecoration(
17 + shape: RoundedRectangleBorder(
18 + borderRadius: BorderRadius.circular(20),
19 + side: BorderSide(color: Colors.blueGrey, width: 3),
20 + ),
21 + color: Colors.white,
22 + ),
23 + child: OutlinedButton(
24 + style: OutlinedButton.styleFrom(
25 + primary: Colors.blueGrey.shade100,
26 + shape: RoundedRectangleBorder(
27 + borderRadius: BorderRadius.circular(20),
28 + side: BorderSide(color: Colors.blueGrey, width: 3),
29 + ),
30 + elevation: 0,
31 + ),
32 + onPressed: () async {
33 + setState(() {
34 + _isProcessing = true;
35 + });
36 + /*await signInWithGoogle().then((result) {
37 + print(result);
38 + if (result != null) {
39 + Navigator.of(context).pop();
40 + Navigator.of(context).pushReplacement(
41 + MaterialPageRoute(
42 + fullscreenDialog: true,
43 + builder: (context) => HomePage(),
44 + ),
45 + );
46 + }
47 + }).catchError((error) {
48 + print('Registration Error: $error');
49 + });
50 + setState(() {
51 + _isProcessing = false;
52 + });*/
53 + },
54 + child: Padding(
55 + padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
56 + child: _isProcessing
57 + ? CircularProgressIndicator(
58 + valueColor: new AlwaysStoppedAnimation<Color>(
59 + Colors.blueGrey,
60 + ),
61 + )
62 + : Row(
63 + mainAxisSize: MainAxisSize.min,
64 + mainAxisAlignment: MainAxisAlignment.center,
65 + children: <Widget>[
66 + Image(
67 + image: AssetImage("assets/images/google_logo.png"),
68 + height: 30.0,
69 + ),
70 + Padding(
71 + padding: const EdgeInsets.only(left: 20),
72 + child: Text(
73 + 'Continue with Google',
74 + style: TextStyle(
75 + fontSize: 20,
76 + color: Colors.blueGrey,
77 + ),
78 + ),
79 + )
80 + ],
81 + ),
82 + ),
83 + ),
84 + );
85 + }
86 +}
1 +import 'package:flutter/material.dart';
2 +
3 +class InfoText extends StatelessWidget {
4 + final String type;
5 + final String text;
6 +
7 + InfoText({required this.type, required this.text});
8 +
9 + @override
10 + Widget build(BuildContext context) {
11 + return Row(
12 + mainAxisSize: MainAxisSize.min,
13 + mainAxisAlignment: MainAxisAlignment.center,
14 + crossAxisAlignment: CrossAxisAlignment.start,
15 + children: [
16 + Text(
17 + '$type: ',
18 + style: TextStyle(
19 + color: Colors.blueGrey[300],
20 + fontSize: 16,
21 + ),
22 + ),
23 + Flexible(
24 + child: Text(
25 + text,
26 + style: TextStyle(
27 + color: Colors.blueGrey[100],
28 + fontSize: 16,
29 + ),
30 + ),
31 + )
32 + ],
33 + );
34 + }
35 +}
1 +import 'package:flutter/material.dart';
2 +
3 +class ResponsiveWidget extends StatelessWidget {
4 + final Widget largeScreen;
5 + final Widget? mediumScreen;
6 + final Widget? smallScreen;
7 +
8 + const ResponsiveWidget(
9 + {Key? key,
10 + required this.largeScreen,
11 + this.mediumScreen,
12 + this.smallScreen})
13 + : super(key: key);
14 +
15 + static bool isSmallScreen(BuildContext context) {
16 + return MediaQuery.of(context).size.width < 800;
17 + }
18 +
19 + static bool isLargeScreen(BuildContext context) {
20 + return MediaQuery.of(context).size.width > 1200;
21 + }
22 +
23 + static bool isMediumScreen(BuildContext context) {
24 + return MediaQuery.of(context).size.width >= 800 &&
25 + MediaQuery.of(context).size.width <= 1200;
26 + }
27 +
28 + @override
29 + Widget build(BuildContext context) {
30 + return LayoutBuilder(
31 + builder: (context, constraints) {
32 + if (constraints.maxWidth > 1200) {
33 + return largeScreen;
34 + } else if (constraints.maxWidth <= 1200 &&
35 + constraints.maxWidth >= 800) {
36 + return mediumScreen ?? largeScreen;
37 + } else {
38 + return smallScreen ?? largeScreen;
39 + }
40 + },
41 + );
42 + }
43 +}
1 +import 'package:easy_dynamic_theme/easy_dynamic_theme.dart';
2 +import 'package:like/screens/home_page.dart';
3 +import 'package:like/utils/authentication.dart';
4 +import 'package:like/widgets/auth_dialog.dart';
5 +import 'package:flutter/material.dart';
6 +
7 +class TopBarContents extends StatefulWidget {
8 + final double opacity;
9 +
10 + TopBarContents(this.opacity);
11 +
12 + @override
13 + _TopBarContentsState createState() => _TopBarContentsState();
14 +}
15 +
16 +class _TopBarContentsState extends State<TopBarContents> {
17 + final List _isHovering = [
18 + false,
19 + false,
20 + false,
21 + false,
22 + false,
23 + false,
24 + false,
25 + false
26 + ];
27 +
28 + bool _isProcessing = false;
29 +
30 + @override
31 + Widget build(BuildContext context) {
32 + var screenSize = MediaQuery.of(context).size;
33 +
34 + return PreferredSize(
35 + preferredSize: Size(screenSize.width, 1000),
36 + child: Container(
37 + color: Theme.of(context).bottomAppBarColor.withOpacity(widget.opacity),
38 + child: Padding(
39 + padding: EdgeInsets.all(20),
40 + child: Row(
41 + crossAxisAlignment: CrossAxisAlignment.center,
42 + children: [
43 + Text(
44 + 'EXPLORE',
45 + style: TextStyle(
46 + color: Colors.blueGrey[100],
47 + fontSize: 20,
48 + fontFamily: 'Montserrat',
49 + fontWeight: FontWeight.w400,
50 + letterSpacing: 3,
51 + ),
52 + ),
53 + Expanded(
54 + child: Row(
55 + mainAxisAlignment: MainAxisAlignment.start,
56 + children: [
57 + SizedBox(width: screenSize.width / 8),
58 + InkWell(
59 + onHover: (value) {
60 + setState(() {
61 + value
62 + ? _isHovering[0] = true
63 + : _isHovering[0] = false;
64 + });
65 + },
66 + onTap: () {},
67 + child: Column(
68 + mainAxisSize: MainAxisSize.min,
69 + children: [
70 + Text(
71 + 'Discover',
72 + style: TextStyle(
73 + color: _isHovering[0]
74 + ? Colors.blue[200]
75 + : Colors.white,
76 + ),
77 + ),
78 + SizedBox(height: 5),
79 + Visibility(
80 + maintainAnimation: true,
81 + maintainState: true,
82 + maintainSize: true,
83 + visible: _isHovering[0],
84 + child: Container(
85 + height: 2,
86 + width: 20,
87 + color: Colors.white,
88 + ),
89 + )
90 + ],
91 + ),
92 + ),
93 + SizedBox(width: screenSize.width / 20),
94 + InkWell(
95 + onHover: (value) {
96 + setState(() {
97 + value
98 + ? _isHovering[1] = true
99 + : _isHovering[1] = false;
100 + });
101 + },
102 + onTap: () {},
103 + child: Column(
104 + mainAxisSize: MainAxisSize.min,
105 + children: [
106 + Text(
107 + 'Contact Us',
108 + style: TextStyle(
109 + color: _isHovering[1]
110 + ? Colors.blue[200]
111 + : Colors.white,
112 + ),
113 + ),
114 + SizedBox(height: 5),
115 + Visibility(
116 + maintainAnimation: true,
117 + maintainState: true,
118 + maintainSize: true,
119 + visible: _isHovering[1],
120 + child: Container(
121 + height: 2,
122 + width: 20,
123 + color: Colors.white,
124 + ),
125 + )
126 + ],
127 + ),
128 + ),
129 + ],
130 + ),
131 + ),
132 + IconButton(
133 + icon: Icon(Icons.brightness_6),
134 + splashColor: Colors.transparent,
135 + highlightColor: Colors.transparent,
136 + color: Colors.white,
137 + onPressed: () {
138 + EasyDynamicTheme.of(context).changeTheme();
139 + },
140 + ),
141 + SizedBox(
142 + width: screenSize.width / 50,
143 + ),
144 + InkWell(
145 + onHover: (value) {
146 + setState(() {
147 + value ? _isHovering[3] = true : _isHovering[3] = false;
148 + });
149 + },
150 + onTap: userEmail == null
151 + ? () {
152 + showDialog(
153 + context: context,
154 + builder: (context) => AuthDialog(),
155 + );
156 + }
157 + : null,
158 + child: userEmail == null
159 + ? Text(
160 + 'Sign in',
161 + style: TextStyle(
162 + color: _isHovering[3] ? Colors.white : Colors.white70,
163 + ),
164 + )
165 + : Row(
166 + children: [
167 + CircleAvatar(
168 + radius: 15,
169 + backgroundImage: imageUrl != null
170 + ? NetworkImage(imageUrl!)
171 + : null,
172 + child: imageUrl == null
173 + ? Icon(
174 + Icons.account_circle,
175 + size: 30,
176 + )
177 + : Container(),
178 + ),
179 + SizedBox(width: 5),
180 + Text(
181 + name ?? userEmail!,
182 + style: TextStyle(
183 + color: _isHovering[3]
184 + ? Colors.white
185 + : Colors.white70,
186 + ),
187 + ),
188 + SizedBox(width: 10),
189 + TextButton(
190 + style: TextButton.styleFrom(
191 + primary: Colors.blueGrey,
192 + shape: RoundedRectangleBorder(
193 + borderRadius: BorderRadius.circular(15),
194 + ),
195 + ),
196 + onPressed: _isProcessing
197 + ? null
198 + : () async {
199 + setState(() {
200 + _isProcessing = true;
201 + });
202 + await signOut().then((result) {
203 + print(result);
204 + Navigator.of(context).pushReplacement(
205 + MaterialPageRoute(
206 + fullscreenDialog: true,
207 + builder: (context) => HomePage(),
208 + ),
209 + );
210 + }).catchError((error) {
211 + print('Sign Out Error: $error');
212 + });
213 + setState(() {
214 + _isProcessing = false;
215 + });
216 + },
217 + child: Padding(
218 + padding: EdgeInsets.only(
219 + top: 8.0,
220 + bottom: 8.0,
221 + ),
222 + child: _isProcessing
223 + ? CircularProgressIndicator()
224 + : Text(
225 + 'Sign out',
226 + style: TextStyle(
227 + fontSize: 14,
228 + color: Colors.white,
229 + ),
230 + ),
231 + ),
232 + )
233 + ],
234 + ),
235 + ),
236 + ],
237 + ),
238 + ),
239 + ),
240 + );
241 + }
242 +}
1 +import 'dart:async';
2 +
3 +import 'package:flutter/material.dart';
4 +
5 +class WebScrollbar extends StatefulWidget {
6 + final Widget child;
7 + final ScrollController controller;
8 + final double heightFraction;
9 + final double width;
10 + final Color color;
11 + final Color backgroundColor;
12 + final bool isAlwaysShown;
13 +
14 + WebScrollbar({
15 + required this.child,
16 + required this.controller,
17 + this.heightFraction = 0.20,
18 + this.width = 8,
19 + this.color = Colors.black45,
20 + this.backgroundColor = Colors.black12,
21 + this.isAlwaysShown = false,
22 + }) : assert(heightFraction < 1.0 && heightFraction > 0.0);
23 +
24 + @override
25 + _WebScrollbarState createState() => _WebScrollbarState();
26 +}
27 +
28 +class _WebScrollbarState extends State<WebScrollbar> {
29 + double _scrollPosition = 0;
30 + late bool _isUpdating;
31 + late Timer timer;
32 +
33 + _scrollListener() {
34 + setState(() {
35 + _scrollPosition = widget.controller.position.pixels;
36 + });
37 + }
38 +
39 + @override
40 + void initState() {
41 + widget.controller.addListener(_scrollListener);
42 + _isUpdating = false;
43 + super.initState();
44 + }
45 +
46 + @override
47 + Widget build(BuildContext context) {
48 + var screenSize = MediaQuery.of(context).size;
49 + double _scrollerHeight = screenSize.height * widget.heightFraction;
50 +
51 + double _topMargin = widget.controller.hasClients
52 + ? ((screenSize.height *
53 + _scrollPosition /
54 + widget.controller.position.maxScrollExtent) -
55 + (_scrollerHeight *
56 + _scrollPosition /
57 + widget.controller.position.maxScrollExtent))
58 + : 0;
59 +
60 + return NotificationListener<ScrollNotification>(
61 + onNotification: (notification) {
62 + if (notification.depth == 0) {
63 + if (notification is ScrollUpdateNotification) {
64 + timer.cancel();
65 + setState(() {
66 + _isUpdating = true;
67 + });
68 + } else {
69 + timer = Timer(Duration(seconds: 5), () {
70 + setState(() {
71 + _isUpdating = false;
72 + });
73 + });
74 + }
75 + }
76 + return true;
77 + },
78 + child: Stack(
79 + children: [
80 + widget.child,
81 + AnimatedOpacity(
82 + opacity: widget.isAlwaysShown
83 + ? 1
84 + : widget.controller.hasClients
85 + ? _isUpdating
86 + ? 1
87 + : 0
88 + : 0,
89 + duration: Duration(milliseconds: 300),
90 + child: Container(
91 + alignment: Alignment.centerRight,
92 + height: MediaQuery.of(context).size.height,
93 + width: widget.width + 2,
94 + margin: EdgeInsets.only(
95 + left: MediaQuery.of(context).size.width - widget.width + 2,
96 + ),
97 + color: widget.backgroundColor,
98 + child: Align(
99 + alignment: Alignment.topCenter,
100 + child: GestureDetector(
101 + child: Container(
102 + height: _scrollerHeight,
103 + width: widget.width,
104 + margin: EdgeInsets.only(
105 + left: 1.0,
106 + right: 1.0,
107 + top: _topMargin,
108 + ),
109 + decoration: BoxDecoration(
110 + color: widget.color,
111 + borderRadius: BorderRadius.all(
112 + Radius.circular(3.0),
113 + ),
114 + ),
115 + ),
116 + onTapCancel: () {
117 + timer = Timer(Duration(seconds: 5), () {
118 + setState(() {
119 + _isUpdating = false;
120 + });
121 + });
122 + },
123 + onTapDown: (details) {
124 + timer.cancel();
125 + setState(() {
126 + _isUpdating = true;
127 + });
128 + },
129 + onVerticalDragUpdate: (dragUpdate) {
130 + widget.controller.position.moveTo(dragUpdate
131 + .globalPosition.dy +
132 + dragUpdate.globalPosition.dy *
133 + (_scrollPosition /
134 + widget.controller.position.maxScrollExtent) -
135 + (_scrollerHeight *
136 + _scrollPosition /
137 + widget.controller.position.maxScrollExtent));
138 +
139 + setState(() {
140 + if (dragUpdate.globalPosition.dy >= 0 &&
141 + _scrollPosition <=
142 + widget.controller.position.maxScrollExtent) {
143 + _scrollPosition = dragUpdate.globalPosition.dy +
144 + dragUpdate.globalPosition.dy *
145 + (_scrollPosition /
146 + widget
147 + .controller.position.maxScrollExtent) -
148 + (_scrollerHeight *
149 + _scrollPosition /
150 + widget.controller.position.maxScrollExtent);
151 + }
152 + });
153 + },
154 + ),
155 + ),
156 + ),
157 + ),
158 + ],
159 + ),
160 + );
161 + }
162 +}
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.8.1"
11 + boolean_selector:
12 + dependency: transitive
13 + description:
14 + name: boolean_selector
15 + url: "https://pub.dartlang.org"
16 + source: hosted
17 + version: "2.1.0"
18 + carousel_slider:
19 + dependency: "direct main"
20 + description:
21 + name: carousel_slider
22 + url: "https://pub.dartlang.org"
23 + source: hosted
24 + version: "4.0.0"
25 + characters:
26 + dependency: transitive
27 + description:
28 + name: characters
29 + url: "https://pub.dartlang.org"
30 + source: hosted
31 + version: "1.1.0"
32 + charcode:
33 + dependency: transitive
34 + description:
35 + name: charcode
36 + url: "https://pub.dartlang.org"
37 + source: hosted
38 + version: "1.3.1"
39 + clock:
40 + dependency: transitive
41 + description:
42 + name: clock
43 + url: "https://pub.dartlang.org"
44 + source: hosted
45 + version: "1.1.0"
46 + collection:
47 + dependency: transitive
48 + description:
49 + name: collection
50 + url: "https://pub.dartlang.org"
51 + source: hosted
52 + version: "1.15.0"
53 + cookie_jar:
54 + dependency: transitive
55 + description:
56 + name: cookie_jar
57 + url: "https://pub.dartlang.org"
58 + source: hosted
59 + version: "3.0.1"
60 + cupertino_icons:
61 + dependency: "direct main"
62 + description:
63 + name: cupertino_icons
64 + url: "https://pub.dartlang.org"
65 + source: hosted
66 + version: "1.0.4"
67 + dio:
68 + dependency: "direct main"
69 + description:
70 + name: dio
71 + url: "https://pub.dartlang.org"
72 + source: hosted
73 + version: "4.0.4"
74 + dio_cookie_manager:
75 + dependency: "direct main"
76 + description:
77 + name: dio_cookie_manager
78 + url: "https://pub.dartlang.org"
79 + source: hosted
80 + version: "2.0.0"
81 + easy_dynamic_theme:
82 + dependency: "direct main"
83 + description:
84 + name: easy_dynamic_theme
85 + url: "https://pub.dartlang.org"
86 + source: hosted
87 + version: "2.2.0"
88 + fake_async:
89 + dependency: transitive
90 + description:
91 + name: fake_async
92 + url: "https://pub.dartlang.org"
93 + source: hosted
94 + version: "1.2.0"
95 + ffi:
96 + dependency: transitive
97 + description:
98 + name: ffi
99 + url: "https://pub.dartlang.org"
100 + source: hosted
101 + version: "1.1.2"
102 + file:
103 + dependency: transitive
104 + description:
105 + name: file
106 + url: "https://pub.dartlang.org"
107 + source: hosted
108 + version: "6.1.2"
109 + firebase_auth:
110 + dependency: "direct main"
111 + description:
112 + name: firebase_auth
113 + url: "https://pub.dartlang.org"
114 + source: hosted
115 + version: "3.3.0"
116 + firebase_auth_platform_interface:
117 + dependency: transitive
118 + description:
119 + name: firebase_auth_platform_interface
120 + url: "https://pub.dartlang.org"
121 + source: hosted
122 + version: "6.1.5"
123 + firebase_auth_web:
124 + dependency: transitive
125 + description:
126 + name: firebase_auth_web
127 + url: "https://pub.dartlang.org"
128 + source: hosted
129 + version: "3.3.1"
130 + firebase_core:
131 + dependency: "direct main"
132 + description:
133 + name: firebase_core
134 + url: "https://pub.dartlang.org"
135 + source: hosted
136 + version: "1.10.2"
137 + firebase_core_platform_interface:
138 + dependency: transitive
139 + description:
140 + name: firebase_core_platform_interface
141 + url: "https://pub.dartlang.org"
142 + source: hosted
143 + version: "4.2.0"
144 + firebase_core_web:
145 + dependency: transitive
146 + description:
147 + name: firebase_core_web
148 + url: "https://pub.dartlang.org"
149 + source: hosted
150 + version: "1.4.0"
151 + flutter:
152 + dependency: "direct main"
153 + description: flutter
154 + source: sdk
155 + version: "0.0.0"
156 + flutter_lints:
157 + dependency: "direct dev"
158 + description:
159 + name: flutter_lints
160 + url: "https://pub.dartlang.org"
161 + source: hosted
162 + version: "1.0.4"
163 + flutter_test:
164 + dependency: "direct dev"
165 + description: flutter
166 + source: sdk
167 + version: "0.0.0"
168 + flutter_web_plugins:
169 + dependency: transitive
170 + description: flutter
171 + source: sdk
172 + version: "0.0.0"
173 + google_sign_in:
174 + dependency: "direct main"
175 + description:
176 + name: google_sign_in
177 + url: "https://pub.dartlang.org"
178 + source: hosted
179 + version: "5.2.1"
180 + google_sign_in_platform_interface:
181 + dependency: transitive
182 + description:
183 + name: google_sign_in_platform_interface
184 + url: "https://pub.dartlang.org"
185 + source: hosted
186 + version: "2.1.0"
187 + google_sign_in_web:
188 + dependency: transitive
189 + description:
190 + name: google_sign_in_web
191 + url: "https://pub.dartlang.org"
192 + source: hosted
193 + version: "0.10.0+3"
194 + http_parser:
195 + dependency: transitive
196 + description:
197 + name: http_parser
198 + url: "https://pub.dartlang.org"
199 + source: hosted
200 + version: "4.0.0"
201 + intl:
202 + dependency: transitive
203 + description:
204 + name: intl
205 + url: "https://pub.dartlang.org"
206 + source: hosted
207 + version: "0.17.0"
208 + js:
209 + dependency: transitive
210 + description:
211 + name: js
212 + url: "https://pub.dartlang.org"
213 + source: hosted
214 + version: "0.6.3"
215 + json_annotation:
216 + dependency: "direct main"
217 + description:
218 + name: json_annotation
219 + url: "https://pub.dartlang.org"
220 + source: hosted
221 + version: "4.4.0"
222 + lints:
223 + dependency: transitive
224 + description:
225 + name: lints
226 + url: "https://pub.dartlang.org"
227 + source: hosted
228 + version: "1.0.1"
229 + matcher:
230 + dependency: transitive
231 + description:
232 + name: matcher
233 + url: "https://pub.dartlang.org"
234 + source: hosted
235 + version: "0.12.10"
236 + meta:
237 + dependency: transitive
238 + description:
239 + name: meta
240 + url: "https://pub.dartlang.org"
241 + source: hosted
242 + version: "1.7.0"
243 + nested:
244 + dependency: transitive
245 + description:
246 + name: nested
247 + url: "https://pub.dartlang.org"
248 + source: hosted
249 + version: "1.0.0"
250 + path:
251 + dependency: transitive
252 + description:
253 + name: path
254 + url: "https://pub.dartlang.org"
255 + source: hosted
256 + version: "1.8.0"
257 + path_provider_linux:
258 + dependency: transitive
259 + description:
260 + name: path_provider_linux
261 + url: "https://pub.dartlang.org"
262 + source: hosted
263 + version: "2.1.2"
264 + path_provider_platform_interface:
265 + dependency: transitive
266 + description:
267 + name: path_provider_platform_interface
268 + url: "https://pub.dartlang.org"
269 + source: hosted
270 + version: "2.0.1"
271 + path_provider_windows:
272 + dependency: transitive
273 + description:
274 + name: path_provider_windows
275 + url: "https://pub.dartlang.org"
276 + source: hosted
277 + version: "2.0.4"
278 + platform:
279 + dependency: transitive
280 + description:
281 + name: platform
282 + url: "https://pub.dartlang.org"
283 + source: hosted
284 + version: "3.1.0"
285 + plugin_platform_interface:
286 + dependency: transitive
287 + description:
288 + name: plugin_platform_interface
289 + url: "https://pub.dartlang.org"
290 + source: hosted
291 + version: "2.0.2"
292 + process:
293 + dependency: transitive
294 + description:
295 + name: process
296 + url: "https://pub.dartlang.org"
297 + source: hosted
298 + version: "4.2.4"
299 + provider:
300 + dependency: "direct main"
301 + description:
302 + name: provider
303 + url: "https://pub.dartlang.org"
304 + source: hosted
305 + version: "6.0.1"
306 + quiver:
307 + dependency: transitive
308 + description:
309 + name: quiver
310 + url: "https://pub.dartlang.org"
311 + source: hosted
312 + version: "3.0.1+1"
313 + shared_preferences:
314 + dependency: transitive
315 + description:
316 + name: shared_preferences
317 + url: "https://pub.dartlang.org"
318 + source: hosted
319 + version: "2.0.9"
320 + shared_preferences_android:
321 + dependency: transitive
322 + description:
323 + name: shared_preferences_android
324 + url: "https://pub.dartlang.org"
325 + source: hosted
326 + version: "2.0.9"
327 + shared_preferences_ios:
328 + dependency: transitive
329 + description:
330 + name: shared_preferences_ios
331 + url: "https://pub.dartlang.org"
332 + source: hosted
333 + version: "2.0.8"
334 + shared_preferences_linux:
335 + dependency: transitive
336 + description:
337 + name: shared_preferences_linux
338 + url: "https://pub.dartlang.org"
339 + source: hosted
340 + version: "2.0.3"
341 + shared_preferences_macos:
342 + dependency: transitive
343 + description:
344 + name: shared_preferences_macos
345 + url: "https://pub.dartlang.org"
346 + source: hosted
347 + version: "2.0.2"
348 + shared_preferences_platform_interface:
349 + dependency: transitive
350 + description:
351 + name: shared_preferences_platform_interface
352 + url: "https://pub.dartlang.org"
353 + source: hosted
354 + version: "2.0.0"
355 + shared_preferences_web:
356 + dependency: transitive
357 + description:
358 + name: shared_preferences_web
359 + url: "https://pub.dartlang.org"
360 + source: hosted
361 + version: "2.0.2"
362 + shared_preferences_windows:
363 + dependency: transitive
364 + description:
365 + name: shared_preferences_windows
366 + url: "https://pub.dartlang.org"
367 + source: hosted
368 + version: "2.0.3"
369 + sky_engine:
370 + dependency: transitive
371 + description: flutter
372 + source: sdk
373 + version: "0.0.99"
374 + source_span:
375 + dependency: transitive
376 + description:
377 + name: source_span
378 + url: "https://pub.dartlang.org"
379 + source: hosted
380 + version: "1.8.1"
381 + stack_trace:
382 + dependency: transitive
383 + description:
384 + name: stack_trace
385 + url: "https://pub.dartlang.org"
386 + source: hosted
387 + version: "1.10.0"
388 + stream_channel:
389 + dependency: transitive
390 + description:
391 + name: stream_channel
392 + url: "https://pub.dartlang.org"
393 + source: hosted
394 + version: "2.1.0"
395 + string_scanner:
396 + dependency: transitive
397 + description:
398 + name: string_scanner
399 + url: "https://pub.dartlang.org"
400 + source: hosted
401 + version: "1.1.0"
402 + term_glyph:
403 + dependency: transitive
404 + description:
405 + name: term_glyph
406 + url: "https://pub.dartlang.org"
407 + source: hosted
408 + version: "1.2.0"
409 + test_api:
410 + dependency: transitive
411 + description:
412 + name: test_api
413 + url: "https://pub.dartlang.org"
414 + source: hosted
415 + version: "0.4.2"
416 + typed_data:
417 + dependency: transitive
418 + description:
419 + name: typed_data
420 + url: "https://pub.dartlang.org"
421 + source: hosted
422 + version: "1.3.0"
423 + vector_math:
424 + dependency: transitive
425 + description:
426 + name: vector_math
427 + url: "https://pub.dartlang.org"
428 + source: hosted
429 + version: "2.1.0"
430 + win32:
431 + dependency: transitive
432 + description:
433 + name: win32
434 + url: "https://pub.dartlang.org"
435 + source: hosted
436 + version: "2.3.1"
437 + xdg_directories:
438 + dependency: transitive
439 + description:
440 + name: xdg_directories
441 + url: "https://pub.dartlang.org"
442 + source: hosted
443 + version: "0.2.0"
444 +sdks:
445 + dart: ">=2.14.0 <3.0.0"
446 + flutter: ">=2.5.0"
1 +name: like
2 +description: A new Flutter project.
3 +
4 +# The following line prevents the package from being accidentally published to
5 +# pub.dev using `flutter pub publish`. This is preferred for private packages.
6 +publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 +
8 +# The following defines the version and build number for your application.
9 +# A version number is three numbers separated by dots, like 1.2.43
10 +# followed by an optional build number separated by a +.
11 +# Both the version and the builder number may be overridden in flutter
12 +# build by specifying --build-name and --build-number, respectively.
13 +# In Android, build-name is used as versionName while build-number used as versionCode.
14 +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 +# Read more about iOS versioning at
17 +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 +version: 1.0.0+1
19 +
20 +environment:
21 + sdk: ">=2.12.0 <3.0.0"
22 +
23 +dependencies:
24 + flutter:
25 + sdk: flutter
26 +
27 + provider: ^6.0.0
28 + cupertino_icons: ^1.0.2
29 + dio: ^4.0.4
30 + dio_cookie_manager: ^2.0.0
31 + carousel_slider: ^4.0.0-nullsafety.0
32 + easy_dynamic_theme: ^2.2.0
33 + google_sign_in: ^5.2.1
34 + firebase_core: ^1.10.2
35 + firebase_auth: ^3.3.0
36 + json_annotation: ^4.4.0
37 +
38 +dev_dependencies:
39 + flutter_test:
40 + sdk: flutter
41 +
42 + flutter_lints: ^1.0.0
43 +
44 +
45 +flutter:
46 +
47 +
48 + uses-material-design: true
49 + fonts:
50 + - family: Montserrat
51 + fonts:
52 + - asset: fonts/Montserrat-Regular.ttf
53 +
54 + - family: Electrolize
55 + fonts:
56 + - asset: fonts/Electrolize-Regular.ttf
57 +
58 + assets:
59 + - assets/images/
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:like/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(TC());
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 +}

917 Bytes

1 +<!DOCTYPE html>
2 +<html>
3 +<head>
4 + <!--
5 + If you are serving your web app in a path other than the root, change the
6 + href value below to reflect the base path you are serving from.
7 +
8 + The path provided below has to start and end with a slash "/" in order for
9 + it to work correctly.
10 +
11 + For more details:
12 + * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
13 +
14 + This is a placeholder for base href that will be replaced by the value of
15 + the `--base-href` argument provided to `flutter build`.
16 + -->
17 + <base href="$FLUTTER_BASE_HREF">
18 +
19 + <meta charset="UTF-8">
20 + <meta content="IE=Edge" http-equiv="X-UA-Compatible">
21 + <meta name="description" content="A new Flutter project.">
22 +
23 + <!-- iOS meta tags & icons -->
24 + <meta name="apple-mobile-web-app-capable" content="yes">
25 + <meta name="apple-mobile-web-app-status-bar-style" content="black">
26 + <meta name="apple-mobile-web-app-title" content="like">
27 + <link rel="apple-touch-icon" href="icons/Icon-192.png">
28 +
29 + <title>like</title>
30 + <link rel="manifest" href="manifest.json">
31 +</head>
32 +<body>
33 + <!-- This script installs service_worker.js to provide PWA functionality to
34 + application. For more information, see:
35 + https://developers.google.com/web/fundamentals/primers/service-workers -->
36 + <script>
37 + var serviceWorkerVersion = null;
38 + var scriptLoaded = false;
39 + function loadMainDartJs() {
40 + if (scriptLoaded) {
41 + return;
42 + }
43 + scriptLoaded = true;
44 + var scriptTag = document.createElement('script');
45 + scriptTag.src = 'main.dart.js';
46 + scriptTag.type = 'application/javascript';
47 + document.body.append(scriptTag);
48 + }
49 +
50 + if ('serviceWorker' in navigator) {
51 + // Service workers are supported. Use them.
52 + window.addEventListener('load', function () {
53 + // Wait for registration to finish before dropping the <script> tag.
54 + // Otherwise, the browser will load the script multiple times,
55 + // potentially different versions.
56 + var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
57 + navigator.serviceWorker.register(serviceWorkerUrl)
58 + .then((reg) => {
59 + function waitForActivation(serviceWorker) {
60 + serviceWorker.addEventListener('statechange', () => {
61 + if (serviceWorker.state == 'activated') {
62 + console.log('Installed new service worker.');
63 + loadMainDartJs();
64 + }
65 + });
66 + }
67 + if (!reg.active && (reg.installing || reg.waiting)) {
68 + // No active web worker and we have installed or are installing
69 + // one for the first time. Simply wait for it to activate.
70 + waitForActivation(reg.installing || reg.waiting);
71 + } else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
72 + // When the app updates the serviceWorkerVersion changes, so we
73 + // need to ask the service worker to update.
74 + console.log('New service worker available.');
75 + reg.update();
76 + waitForActivation(reg.installing);
77 + } else {
78 + // Existing service worker is still good.
79 + console.log('Loading app from service worker.');
80 + loadMainDartJs();
81 + }
82 + });
83 +
84 + // If service worker doesn't succeed in a reasonable amount of time,
85 + // fallback to plaint <script> tag.
86 + setTimeout(() => {
87 + if (!scriptLoaded) {
88 + console.warn(
89 + 'Failed to load app from service worker. Falling back to plain <script> tag.',
90 + );
91 + loadMainDartJs();
92 + }
93 + }, 4000);
94 + });
95 + } else {
96 + // Service workers not supported. Just drop the <script> tag.
97 + loadMainDartJs();
98 + }
99 + </script>
100 +</body>
101 +</html>
1 +{
2 + "name": "like",
3 + "short_name": "like",
4 + "start_url": ".",
5 + "display": "standalone",
6 + "background_color": "#0175C2",
7 + "theme_color": "#0175C2",
8 + "description": "A new Flutter project.",
9 + "orientation": "portrait-primary",
10 + "prefer_related_applications": false,
11 + "icons": [
12 + {
13 + "src": "icons/Icon-192.png",
14 + "sizes": "192x192",
15 + "type": "image/png"
16 + },
17 + {
18 + "src": "icons/Icon-512.png",
19 + "sizes": "512x512",
20 + "type": "image/png"
21 + },
22 + {
23 + "src": "icons/Icon-maskable-192.png",
24 + "sizes": "192x192",
25 + "type": "image/png",
26 + "purpose": "maskable"
27 + },
28 + {
29 + "src": "icons/Icon-maskable-512.png",
30 + "sizes": "512x512",
31 + "type": "image/png",
32 + "purpose": "maskable"
33 + }
34 + ]
35 +}