Initial commit
|
@ -0,0 +1,50 @@
|
|||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
migrate_working_dir/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Android Studio will place build artifacts here
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
# Custom
|
||||
/lib/secrets.dart
|
|
@ -0,0 +1,36 @@
|
|||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled.
|
||||
|
||||
version:
|
||||
revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
channel: stable
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
- platform: android
|
||||
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
- platform: ios
|
||||
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
- platform: web
|
||||
create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
|
@ -0,0 +1,16 @@
|
|||
# furman_now
|
||||
|
||||
A new Flutter project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
|
@ -0,0 +1,29 @@
|
|||
# This file configures the analyzer, which statically analyzes Dart code to
|
||||
# check for errors, warnings, and lints.
|
||||
#
|
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||
# invoked from the command line by running `flutter analyze`.
|
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
# included above or to enable additional rules. A list of all available lints
|
||||
# and their documentation is published at
|
||||
# https://dart-lang.github.io/linter/lints/index.html.
|
||||
#
|
||||
# Instead of disabling a lint rule for the entire project in the
|
||||
# section below, it can also be suppressed for a single line of code
|
||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
|
@ -0,0 +1,13 @@
|
|||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
|
@ -0,0 +1,71 @@
|
|||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion flutter.compileSdkVersion
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "edu.furman.now"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
targetSdkVersion flutter.targetSdkVersion
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="edu.furman.now.furman_now">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
|
@ -0,0 +1,37 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="edu.furman.now.furman_now">
|
||||
<application
|
||||
android:label="Furman Now!"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
|
||||
<!-- Permissions -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,6 @@
|
|||
package edu.furman.now.furman_now
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity: FlutterActivity() {
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
|
@ -0,0 +1,53 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<group android:scaleX="0.8983333"
|
||||
android:scaleY="0.8983333"
|
||||
android:translateX="30.894867"
|
||||
android:translateY="21.66">
|
||||
<path
|
||||
android:pathData="M11.91,57.52v11.82c0.59,0.24 1.19,0.47 1.8,0.67v-5.21h0c0.03,-7.11 10.4,-7.1 10.42,0h0v7.16c1.04,0.05 2.1,0.05 3.14,0v-7.16h0c-0.09,-6.93 10.56,-7.34 10.43,0h0v5.21c0.62,-0.21 1.22,-0.43 1.82,-0.68v-11.82H11.91Z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M10.79,57.52v11.36c-0.93,-0.41 -1.83,-0.85 -2.71,-1.33v-10.03h2.71Z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M43.37,57.52v10.01c-0.88,0.47 -1.79,0.92 -2.71,1.33v-11.34h2.71Z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M6.5,56.51v-2.2H44.95v2.2H6.5Z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M40.65,26.85h2.71v26.39h-2.71z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M36.02,49.08h3.5v4.15h-3.5z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M22.98,49.08h5.45v4.15h-5.45z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M15.39,49.08l0,4.16l-3.49,0l0,-4.16l0.01,0l3.48,0z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M8.08,26.85h2.71v26.39h-2.71z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M39.53,26.85v21.12h-1.82v-13.83h0c-0.03,-7.11 -10.4,-7.11 -10.43,0h0v13.83h-3.14v-13.83h0c-0.02,-7.11 -10.4,-7.11 -10.42,0h0v13.83h-1.8V26.85h27.62Z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M6.5,23.51h38.45v2.2h-38.45z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M25.72,0l1.33,8.47l-2.66,0l1.33,-8.47z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M25.73,9.8c0.83,0 1.51,0.68 1.51,1.52s-0.68,1.51 -1.51,1.51 -1.52,-0.68 -1.52,-1.51 0.68,-1.52 1.52,-1.52Z"
|
||||
android:fillColor="#fff"/>
|
||||
<path
|
||||
android:pathData="M51.44,22.45l-51.44,0l24.35,-6.92l0,-1.55l2.75,0l0,1.55l24.34,6.92z"
|
||||
android:fillColor="#fff"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#53307F</color>
|
||||
</resources>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -0,0 +1,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="edu.furman.now.furman_now">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
|
@ -0,0 +1,31 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.6.10'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.2.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
|
@ -0,0 +1,6 @@
|
|||
#Fri Jun 23 08:50:38 CEST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
|
|
@ -0,0 +1,11 @@
|
|||
include ':app'
|
||||
|
||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
||||
def properties = new Properties()
|
||||
|
||||
assert localPropertiesFile.exists()
|
||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
||||
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path style="fill:#4f2984;" d="M66.12,90.3c0-.12,.04-.23,.04-.35,0-3.89-3.15-7.04-7.03-7.04s-7.03,3.15-7.03,7.04c0,.12,.03,.23,.04,.35h-.03v9.7c4.9-.2,9.62-1.11,14.06-2.63v-7.07h-.03Z"/><path style="fill:#4f2984;" d="M47.84,90.3c0-.12,.03-.23,.03-.35,0-3.89-3.15-7.04-7.03-7.04s-7.03,3.15-7.03,7.04c0,.12,.03,.23,.03,.35h-.03v7.06c4.44,1.52,9.16,2.44,14.06,2.64v-9.7h-.03Z"/><path style="fill:#4f2984;" d="M50,0C22.39,0,0,22.4,0,50.03c0,19.01,10.6,35.55,26.21,44.01v-13.55h3.67v15.34c.5,.22,1,.43,1.5,.63v-15.97h37.24v15.97c.51-.2,1.01-.41,1.5-.63v-15.34h3.67v13.55c15.61-8.46,26.21-25,26.21-44.01C100,22.4,77.62,0,50,0Zm-.01,3.02v-.07s.02-.07,.02-.07v.14l1.78,11.35h-3.59l1.78-11.35Zm.01,13.14c1.13,0,2.04,.91,2.04,2.04s-.91,2.04-2.04,2.04-2.04-.91-2.04-2.04,.91-2.04,2.04-2.04Zm25.92,62.97H24.08v-2.97h51.83v2.97Zm-49.7-4.41V39.15h3.67v35.57h-3.67Zm39.94-7.1v-18.65h-.03c0-.12,.04-.23,.04-.35,0-3.89-3.15-7.04-7.03-7.04s-7.03,3.15-7.03,7.04c0,.12,.03,.23,.04,.35h-.03v18.65h-4.22v-18.65h-.03c0-.12,.03-.23,.03-.35,0-3.89-3.15-7.04-7.03-7.04s-7.03,3.15-7.03,7.04c0,.12,.03,.23,.03,.35h-.03v18.65h-2.43v-28.46h37.24v28.46h-2.47Zm2.45,1.5v5.6h-4.71v-5.6h4.71Zm-14.94,0v5.6h-7.35v-5.6h7.35Zm-17.58,0v5.6h-4.71v-5.6h4.71Zm34.05,5.6V39.15h3.67v35.57h-3.67Zm5.79-37.11H24.08v-2.97h51.83v2.97Zm-25.7-4.39H15.33l32.82-9.34v-2.08h3.71v2.08l32.82,9.34H50.21Z"/></svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 183.81 499.41"><path d="M92.03,0c-2.26-.05-4.54,1.2-5.45,3.75L1.31,242.08c-.93,2.61-1.36,5.35-1.3,8.09H92.03V0Z" style="fill:#d83f31;"/><path d="M0,250.16c.05,2.43,.47,4.85,1.3,7.17l85.27,238.33c.91,2.55,3.19,3.79,5.45,3.75V250.16H0Z" style="fill:#c2c2c1;"/><path d="M182.5,242.08L97.24,3.75C96.36,1.29,94.2,.05,92.03,0V250.16h91.78c.06-2.73-.37-5.47-1.3-8.09Z" style="fill:#c33527;"/><path d="M92.03,250.16v249.24c2.18-.05,4.33-1.29,5.21-3.75l85.27-238.33c.83-2.32,1.25-4.74,1.3-7.17H92.03Z" style="fill:#dbdada;"/><circle cx="92.03" cy="250.16" r="34.17" style="fill:#fff;"/></svg>
|
After Width: | Height: | Size: 681 B |
|
@ -0,0 +1,34 @@
|
|||
**/dgph
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
*.perspectivev3
|
||||
**/*sync/
|
||||
.sconsign.dblite
|
||||
.tags*
|
||||
**/.vagrant/
|
||||
**/DerivedData/
|
||||
Icon?
|
||||
**/Pods/
|
||||
**/.symlinks/
|
||||
profile
|
||||
xcuserdata
|
||||
**/.generated/
|
||||
Flutter/App.framework
|
||||
Flutter/Flutter.framework
|
||||
Flutter/Flutter.podspec
|
||||
Flutter/Generated.xcconfig
|
||||
Flutter/ephemeral/
|
||||
Flutter/app.flx
|
||||
Flutter/app.zip
|
||||
Flutter/flutter_assets/
|
||||
Flutter/flutter_export_environment.sh
|
||||
ServiceDefinitions.json
|
||||
Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.pbxuser
|
||||
!default.perspectivev3
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>9.0</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
|
@ -0,0 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
|
@ -0,0 +1,41 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '9.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
PODS:
|
||||
- Flutter (1.0.0)
|
||||
- path_provider_ios (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
path_provider_ios:
|
||||
:path: ".symlinks/plugins/path_provider_ios/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
|
||||
|
||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||
|
||||
COCOAPODS: 1.11.3
|
|
@ -0,0 +1,549 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 50;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
11E039BAA958A82F61CA8CF4 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 445C012451AF63F270E13685 /* Pods_Runner.framework */; };
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
3249BE4DF8F2DD8FFDBEF7DC /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
445C012451AF63F270E13685 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
E0924751F238036F68F3BE44 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
F1A21E9608592ADA54209C54 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
11E039BAA958A82F61CA8CF4 /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
18B68695A78F6AE81A12B248 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3249BE4DF8F2DD8FFDBEF7DC /* Pods-Runner.debug.xcconfig */,
|
||||
E0924751F238036F68F3BE44 /* Pods-Runner.release.xcconfig */,
|
||||
F1A21E9608592ADA54209C54 /* Pods-Runner.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */,
|
||||
);
|
||||
name = Flutter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146E51CF9000F007C117D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
18B68695A78F6AE81A12B248 /* Pods */,
|
||||
F2C3C45531977DF5F83A8199 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146EF1CF9000F007C117D /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
97C147021CF9000F007C117D /* Info.plist */,
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
||||
);
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F2C3C45531977DF5F83A8199 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
445C012451AF63F270E13685 /* Pods_Runner.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
8CBD88BD92A95B890D828A7D /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
F18EE307CA050517163ABD82 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Runner;
|
||||
productName = Runner;
|
||||
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1300;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
LastSwiftMigration = 1100;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 97C146E51CF9000F007C117D;
|
||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
97C146ED1CF9000F007C117D /* Runner */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||
};
|
||||
8CBD88BD92A95B890D828A7D /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
F18EE307CA050517163ABD82 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C146FB1CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C147001CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
249021D4217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = edu.furman.now.furmanNow;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
97C147031CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147041CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
97C147061CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = edu.furman.now.furmanNow;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147071CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = edu.furman.now.furmanNow;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147031CF9000F007C117D /* Debug */,
|
||||
97C147041CF9000F007C117D /* Release */,
|
||||
249021D3217E4FDB00AE95B9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147061CF9000F007C117D /* Debug */,
|
||||
97C147071CF9000F007C117D /* Release */,
|
||||
249021D4217E4FDB00AE95B9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1300"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,13 @@
|
|||
import UIKit
|
||||
import Flutter
|
||||
|
||||
@UIApplicationMain
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 564 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 68 B |
After Width: | Height: | Size: 68 B |
|
@ -0,0 +1,5 @@
|
|||
# Launch Screen Assets
|
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||
|
||||
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.
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
</resources>
|
||||
</document>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Furman Now</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>furman_now</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1 @@
|
|||
#import "GeneratedPluginRegistrant.h"
|
|
@ -0,0 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/app.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const App());
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/screens/events/index.dart';
|
||||
import 'package:furman_now/src/screens/home/index.dart';
|
||||
import 'package:furman_now/src/screens/info/index.dart';
|
||||
import 'package:furman_now/src/screens/map/index.dart';
|
||||
import 'package:furman_now/src/screens/student_id/index.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:navbar_router/navbar_router.dart';
|
||||
|
||||
class App extends StatelessWidget {
|
||||
const App({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Furman Now!',
|
||||
home: const MainPage(),
|
||||
theme: myFurmanTheme,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MainPage extends StatefulWidget {
|
||||
const MainPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MainPage> createState() => _MainPageState();
|
||||
}
|
||||
|
||||
class _MainPageState extends State<MainPage> {
|
||||
List<NavbarItem> items = [
|
||||
NavbarItem(Icons.home_outlined, 'Home', backgroundColor: colors[0]),
|
||||
NavbarItem(Icons.map_outlined, 'Map', backgroundColor: colors[0]),
|
||||
NavbarItem(Icons.person_outline, 'Meal ID', backgroundColor: colors[0]),
|
||||
NavbarItem(Icons.calendar_month_outlined, 'Events', backgroundColor: colors[0]),
|
||||
NavbarItem(Icons.info_outline, 'Info', backgroundColor: colors[0]),
|
||||
];
|
||||
|
||||
final Map<int, Map<String, Widget>> _routes = const {
|
||||
0: {
|
||||
'/': HomeScreen(),
|
||||
// FeedDetail.route: FeedDetail(),
|
||||
},
|
||||
1: {
|
||||
'/': MapScreen(),
|
||||
// ProductDetail.route: ProductDetail(),
|
||||
// ProductComments.route: ProductComments(),
|
||||
},
|
||||
2: {
|
||||
'/': StudentIdScreen(),
|
||||
// ProductDetail.route: ProductDetail(),
|
||||
// ProductComments.route: ProductComments(),
|
||||
},
|
||||
3: {
|
||||
'/': EventsScreen(),
|
||||
// ProfileEdit.route: ProfileEdit(),
|
||||
},
|
||||
4: {
|
||||
'/': InfoScreen(),
|
||||
// ProfileEdit.route: ProfileEdit(),
|
||||
},
|
||||
};
|
||||
|
||||
void showSnackBar() {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
behavior: SnackBarBehavior.floating,
|
||||
duration: Duration(milliseconds: 600),
|
||||
margin: EdgeInsets.only(
|
||||
bottom: kBottomNavigationBarHeight + 2, right: 2, left: 2),
|
||||
content: Text('Tap back button again to exit'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void hideSnackBar() {
|
||||
ScaffoldMessenger.of(context).hideCurrentSnackBar();
|
||||
}
|
||||
|
||||
DateTime oldTime = DateTime.now();
|
||||
DateTime newTime = DateTime.now();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = MediaQuery.of(context).size;
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: NavbarRouter(
|
||||
errorBuilder: (context) {
|
||||
return const Center(child: Text('Error 404'));
|
||||
},
|
||||
isDesktop: size.width > 600 ? true : false,
|
||||
onBackButtonPressed: (isExitingApp) {
|
||||
if (isExitingApp) {
|
||||
newTime = DateTime.now();
|
||||
int difference = newTime.difference(oldTime).inMilliseconds;
|
||||
oldTime = newTime;
|
||||
if (difference < 1000) {
|
||||
hideSnackBar();
|
||||
return isExitingApp;
|
||||
} else {
|
||||
showSnackBar();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return isExitingApp;
|
||||
}
|
||||
},
|
||||
destinationAnimationCurve: Curves.fastOutSlowIn,
|
||||
destinationAnimationDuration: 600,
|
||||
decoration: NavbarDecoration(
|
||||
selectedLabelTextStyle: const TextStyle(color: Colors.deepPurple),
|
||||
showUnselectedLabels: true,
|
||||
unselectedLabelTextStyle:
|
||||
const TextStyle(color: Colors.black, fontSize: 10),
|
||||
selectedIconTheme: const IconThemeData(color: Colors.deepPurple),
|
||||
isExtended: size.width > 800 ? true : false,
|
||||
navbarType: BottomNavigationBarType.fixed),
|
||||
// onChanged: (x) {
|
||||
// debugPrint('index changed $x');
|
||||
// },
|
||||
backButtonBehavior: BackButtonBehavior.rememberHistory,
|
||||
destinations: [
|
||||
for (int i = 0; i < items.length; i++)
|
||||
DestinationRouter(
|
||||
navbarItem: items[i],
|
||||
destinations: [
|
||||
for (int j = 0; j < _routes[i]!.keys.length; j++)
|
||||
Destination(
|
||||
route: _routes[i]!.keys.elementAt(j),
|
||||
widget: _routes[i]!.values.elementAt(j),
|
||||
),
|
||||
],
|
||||
initialRoute: _routes[i]!.keys.first,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> navigate(BuildContext context, String route,
|
||||
{bool isDialog = false,
|
||||
bool isRootNavigator = true,
|
||||
Map<String, dynamic>? arguments}) =>
|
||||
Navigator.of(context, rootNavigator: isRootNavigator)
|
||||
.pushNamed(route, arguments: arguments);
|
|
@ -0,0 +1,49 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class MainLayout extends StatelessWidget {
|
||||
const MainLayout({
|
||||
Key? key,
|
||||
this.body,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget? body;
|
||||
|
||||
void _onItemTapped(int index) {
|
||||
// Navigate to the second screen using a named route.
|
||||
// Navigator.pushNamed(context, '/second');
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: body,
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
items: const <BottomNavigationBarItem>[
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.home),
|
||||
label: 'Home',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.map),
|
||||
label: 'Map',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.perm_identity),
|
||||
label: 'Meal Card',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.calendar_month),
|
||||
label: 'Events',
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
icon: Icon(Icons.info_outline),
|
||||
label: 'Info',
|
||||
),
|
||||
],
|
||||
currentIndex: 0,
|
||||
selectedItemColor: Colors.grey[700],
|
||||
onTap: _onItemTapped,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/screens/home/index.dart';
|
||||
|
||||
Route routes(RouteSettings settings) {
|
||||
switch (settings.name) {
|
||||
case '/':
|
||||
return MaterialPageRoute(builder: (_) => const HomeScreen());
|
||||
// case '/home':
|
||||
// return MaterialPageRoute(builder: (_) => HomeScreen());
|
||||
// case '/auth':
|
||||
// return MaterialPageRoute(builder: (_) => AuthenticationScreen());
|
||||
default:
|
||||
return MaterialPageRoute(builder: (_) => const HomeScreen());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/utils/date_range.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:furman_now/src/widgets/header.dart';
|
||||
import 'package:furman_now/src/widgets/home/events/events_list.dart';
|
||||
import 'package:furman_now/src/widgets/scroll_view_height.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class EventsScreen extends StatelessWidget {
|
||||
const EventsScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: Colors.grey[100],
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
|
||||
child: Stack(
|
||||
fit: StackFit.loose,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||
width: double.infinity,
|
||||
height: 100,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.calendar_month_outlined, size: 35, color: Colors.grey[700]),
|
||||
const SizedBox(width: 12),
|
||||
Text("Events", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
ScrollViewWithHeight(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
margin: const EdgeInsets.only(top: 100),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const HeaderWidget(title: "Today"),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: EventsList()
|
||||
),
|
||||
const HeaderWidget(title: "Tomorrow"),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: EventsList(dateRange: constructDateRange(
|
||||
DateTime.now().add(const Duration(days: 1)),
|
||||
DateTime.now().add(const Duration(days: 1)),
|
||||
)),
|
||||
),
|
||||
...[for(var i=2; i<7; i+=1) i].map((i) {
|
||||
var date = DateTime.now().add(Duration(days: i));
|
||||
var dayName = DateFormat('EEEE').format(date);
|
||||
return Wrap(
|
||||
children: [
|
||||
HeaderWidget(title: dayName),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: EventsList(dateRange: constructDateRange(
|
||||
date,
|
||||
date,
|
||||
)),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
Center(child:
|
||||
Wrap(
|
||||
direction: Axis.vertical,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: const [
|
||||
Text("Need more events?"),
|
||||
Text("Syncdin"),
|
||||
Text("Athletics"),
|
||||
Text("CLPs"),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/utils/greeting.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:furman_now/src/widgets/header.dart';
|
||||
import 'package:furman_now/src/widgets/home/events/events_list.dart';
|
||||
import 'package:furman_now/src/widgets/home/restaurants/restaurants_list.dart';
|
||||
import 'package:furman_now/src/widgets/home/transportation/transportation_card.dart';
|
||||
import 'package:furman_now/src/widgets/scroll_view_height.dart';
|
||||
|
||||
class HomeScreen extends StatelessWidget {
|
||||
const HomeScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: const Color(0xffb7acc9),
|
||||
child: SafeArea(
|
||||
child: Container(
|
||||
color: Colors.grey[100],
|
||||
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
|
||||
child: Stack(
|
||||
fit: StackFit.loose,
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: <Color>[
|
||||
Color(0xffb7acc9),
|
||||
Color(0xffb7acc9),
|
||||
], // Gradient from https://learnui.design/tools/gradient-generator.html
|
||||
tileMode: TileMode.mirror,
|
||||
),
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(40),
|
||||
width: double.infinity,
|
||||
height: 200,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("${greeting()},\nMichael", style: furmanTextStyle(const TextStyle(color: Color(0xff26183d), fontSize: 36, fontWeight: FontWeight.w800))),
|
||||
const SizedBox(height: 5),
|
||||
Text("It's 76º and partly cloudy", style: furmanTextStyle(const TextStyle(color: Color(0xff26183d), fontSize: 16, fontWeight: FontWeight.w500))),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
ScrollViewWithHeight(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
margin: const EdgeInsets.only(top: 200),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const HeaderWidget(
|
||||
title: "Today's Events",
|
||||
link: HeaderLink(text: "View more", href: ""),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: EventsList(),
|
||||
),
|
||||
const HeaderWidget(title: "Food & Dining"),
|
||||
const RestaurantsList(),
|
||||
const HeaderWidget(title: "Transportation"),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
||||
child: TransportationCard(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:furman_now/src/widgets/info/info_card.dart';
|
||||
import 'package:furman_now/src/widgets/scroll_view_height.dart';
|
||||
|
||||
class InfoScreen extends StatelessWidget {
|
||||
const InfoScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: Colors.grey[100],
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
|
||||
child: Stack(
|
||||
fit: StackFit.loose,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||
width: double.infinity,
|
||||
height: 100,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.info_outline, size: 35, color: Colors.grey[700]),
|
||||
const SizedBox(width: 12),
|
||||
Text("Info", style: furmanTextStyle(TextStyle(color: Colors.grey[900], fontSize: 28, fontWeight: FontWeight.w700))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
ScrollViewWithHeight(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(30)),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
|
||||
margin: const EdgeInsets.only(top: 100),
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
InfoCard(
|
||||
color: Colors.red.shade50,
|
||||
icon: Icons.local_hospital,
|
||||
title: "Health and Safety",
|
||||
description: "Important contact information and links regarding student health and safety.",
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
InfoCard(
|
||||
color: Colors.deepPurple.shade50,
|
||||
icon: Icons.phone,
|
||||
title: "Contacts",
|
||||
description: "Important contact information and links regarding student health and safety.",
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
InfoCard(
|
||||
color: Colors.blue.shade50,
|
||||
icon: Icons.access_time,
|
||||
title: "Hours",
|
||||
description: "Important contact information and links regarding student health and safety.",
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:furman_now/src/widgets/map/filter_chip.dart';
|
||||
import 'package:furman_now/src/widgets/map/rotate_compass.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
class MapScreen extends StatefulWidget {
|
||||
const MapScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MapScreen> createState() => _MapScreenState();
|
||||
}
|
||||
|
||||
class _MapScreenState extends State<MapScreen>
|
||||
with SingleTickerProviderStateMixin {
|
||||
final MapController _mapController = MapController();
|
||||
|
||||
late final AnimationController _animationController = AnimationController(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
vsync: this,
|
||||
);
|
||||
|
||||
var _rotation = 0.0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_mapController.mapEventStream.listen((event) {
|
||||
if (event is MapEventRotate) {
|
||||
setState(() {
|
||||
_rotation = _mapController.rotation * (2 * pi) / 360;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_animationController.dispose();
|
||||
}
|
||||
|
||||
void resetRotation() async {
|
||||
// take the shortest rotation path
|
||||
var end = _mapController.rotation > 180 ? 360.0 : 0.0;
|
||||
var animation = Tween<double>(
|
||||
begin: _mapController.rotation,
|
||||
end: end,
|
||||
).animate(CurvedAnimation(
|
||||
parent: _animationController,
|
||||
curve: Curves.easeInOut,
|
||||
));
|
||||
|
||||
animationListener() {
|
||||
_mapController.rotate(animation.value);
|
||||
}
|
||||
|
||||
animation.addListener(animationListener);
|
||||
|
||||
await _animationController.forward();
|
||||
|
||||
animation.removeListener(animationListener);
|
||||
_animationController.reset();
|
||||
|
||||
_mapController.rotate(0);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: const Color(0xffb7acc9),
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
|
||||
child: Stack(
|
||||
children: [
|
||||
FlutterMap(
|
||||
mapController: _mapController,
|
||||
options: MapOptions(
|
||||
center: LatLng(34.925926, -82.439397),
|
||||
enableMultiFingerGestureRace: true,
|
||||
rotationWinGestures: MultiFingerGesture.all,
|
||||
pinchZoomThreshold: 0.2,
|
||||
rotationThreshold: 8,
|
||||
zoom: 15,
|
||||
minZoom: 12,
|
||||
maxZoom: 18,
|
||||
),
|
||||
layers: [
|
||||
TileLayerOptions(
|
||||
urlTemplate:
|
||||
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
userAgentPackageName: 'edu.furman.now',
|
||||
),
|
||||
],
|
||||
nonRotatedChildren: [
|
||||
AttributionWidget(
|
||||
attributionBuilder: (BuildContext context) {
|
||||
return const ColoredBox(
|
||||
color: Color(0xCCFFFFFF),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(3),
|
||||
child: Text("©️ OpenStreetMap contributors"),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
top: 12,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 50,
|
||||
padding: const EdgeInsets.only(left: 10, right: 20),
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(60)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0x33000000),
|
||||
blurRadius: 8,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
SvgPicture.asset("assets/images/bell-tower.svg", color: Theme.of(context).primaryColor, height: 32),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
"Search locations",
|
||||
style: furmanTextStyle(TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey.shade500,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// const SizedBox(height: 12),
|
||||
SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Wrap(
|
||||
spacing: 6,
|
||||
children: const [
|
||||
MapFilterChip(icon: Icons.restaurant, text: "Restaurants"),
|
||||
MapFilterChip(icon: Icons.train, text: "Transportation"),
|
||||
MapFilterChip(icon: Icons.school, text: "Campus Buildings"),
|
||||
],
|
||||
),
|
||||
),
|
||||
MapRotateCompass(rotation: _rotation, resetRotation: resetRotation),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:barcode_widget/barcode_widget.dart';
|
||||
import 'package:furman_now/src/services/get_app/barcode/barcode_service.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
|
||||
class StudentIdScreen extends StatefulWidget {
|
||||
const StudentIdScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StudentIdScreen> createState() => _StudentIdScreenState();
|
||||
}
|
||||
|
||||
class _StudentIdScreenState extends State<StudentIdScreen> {
|
||||
String barcodeNumber = BarcodeService.generateGetBarcode();
|
||||
Timer? timer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
timer = Timer.periodic(
|
||||
const Duration(seconds: 10),
|
||||
updateBarcode,
|
||||
);
|
||||
}
|
||||
|
||||
void updateBarcode(Timer timer) {
|
||||
setState(() {
|
||||
barcodeNumber = BarcodeService.generateGetBarcode();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Container(
|
||||
color: const Color(0xffb7acc9),
|
||||
child: SafeArea(
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(40),
|
||||
children: [
|
||||
Text(
|
||||
"Furman ID",
|
||||
style: furmanTextStyle(const TextStyle(color: Color(0xff26183d), fontSize: 36, fontWeight: FontWeight.w800)),
|
||||
),
|
||||
const SizedBox(height: 200),
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
// hack since the barcode has a weird intrinsic size for some reason
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
return BarcodeWidget(
|
||||
barcode: Barcode.pdf417(moduleHeight: 4),
|
||||
data: barcodeNumber,
|
||||
margin: const EdgeInsets.all(10),
|
||||
height: constraints.maxWidth / 3,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
class Event {
|
||||
Event({
|
||||
required this.title,
|
||||
required this.time,
|
||||
required this.location,
|
||||
required this.category
|
||||
});
|
||||
|
||||
final String title;
|
||||
final DateTime time;
|
||||
final String location;
|
||||
final String category;
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:furman_now/src/services/events/event.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class EventsService {
|
||||
static Future<List<Event>> fetchEvents() async {
|
||||
var athleticsEvents = await fetchAthleticsEvents();
|
||||
var clpEvents = await fetchClpEvents();
|
||||
List<Event> eventsList = List.from(athleticsEvents)..addAll(clpEvents);
|
||||
eventsList.sort((Event a, Event b) => a.time.compareTo(b.time));
|
||||
return eventsList;
|
||||
}
|
||||
|
||||
static Future<Iterable<AthleticsEvent>> fetchAthleticsEvents() async {
|
||||
final response = await http
|
||||
.get(Uri.parse("https://cs.furman.edu/~csdaemon/FUNow/athleticsGet.php"));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// If the server did return a 200 OK response,
|
||||
// then parse the JSON.
|
||||
final eventsJson = jsonDecode(response.body);
|
||||
return (eventsJson["results"] as List<dynamic>).map((event) =>
|
||||
AthleticsEvent.fromJson(event)
|
||||
);
|
||||
} else {
|
||||
// If the server did not return a 200 OK response,
|
||||
// then throw an exception.
|
||||
throw Exception('Failed to load athletics events.');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Iterable<ClpEvent>> fetchClpEvents() async {
|
||||
final response = await http
|
||||
.get(Uri.parse("https://cs.furman.edu/~csdaemon/FUNow/clpGet.php"));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// If the server did return a 200 OK response,
|
||||
// then parse the JSON.
|
||||
final eventsJson = jsonDecode(response.body);
|
||||
return (eventsJson["results"] as List<dynamic>).map((event) =>
|
||||
ClpEvent.fromJson(event)
|
||||
);
|
||||
} else {
|
||||
// If the server did not return a 200 OK response,
|
||||
// then throw an exception.
|
||||
throw Exception('Failed to load athletics events.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AthleticsEvent implements Event {
|
||||
@override
|
||||
final String title;
|
||||
@override
|
||||
final DateTime time;
|
||||
@override
|
||||
final String location;
|
||||
@override
|
||||
final String category = "Athletics";
|
||||
|
||||
final String sportTitle;
|
||||
final String sportShort;
|
||||
final AthleticsEventLocation locationIndicator;
|
||||
final String opponent;
|
||||
|
||||
AthleticsEvent._({
|
||||
required this.title,
|
||||
required this.time,
|
||||
required this.location,
|
||||
|
||||
required this.sportTitle,
|
||||
required this.sportShort,
|
||||
required this.locationIndicator,
|
||||
required this.opponent,
|
||||
});
|
||||
|
||||
factory AthleticsEvent({
|
||||
required time,
|
||||
required location,
|
||||
required sportTitle,
|
||||
required sportShort,
|
||||
required locationIndicator,
|
||||
required opponent,
|
||||
}) {
|
||||
// Determine AthleticsEventLocation from string
|
||||
AthleticsEventLocation eventLocationIndicator;
|
||||
switch(locationIndicator) {
|
||||
case ("H"):
|
||||
eventLocationIndicator = AthleticsEventLocation.home;
|
||||
break;
|
||||
case ("A"):
|
||||
eventLocationIndicator = AthleticsEventLocation.away;
|
||||
break;
|
||||
case ("N"):
|
||||
default:
|
||||
eventLocationIndicator = AthleticsEventLocation.neither;
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate event title
|
||||
var eventTitleSeparator =
|
||||
eventLocationIndicator == AthleticsEventLocation.away
|
||||
? "at"
|
||||
: "vs";
|
||||
|
||||
return AthleticsEvent._(
|
||||
title: '$sportTitle $eventTitleSeparator $opponent',
|
||||
time: time,
|
||||
location: location,
|
||||
sportTitle: sportTitle,
|
||||
sportShort: sportShort,
|
||||
locationIndicator: eventLocationIndicator,
|
||||
opponent: opponent,
|
||||
);
|
||||
}
|
||||
|
||||
factory AthleticsEvent.fromJson(Map<String, dynamic> json) {
|
||||
return AthleticsEvent(
|
||||
sportTitle: json["sportTitle"],
|
||||
sportShort: json["sportShort"],
|
||||
time: DateTime.parse(json["eventdate"]),
|
||||
location: json["location"],
|
||||
locationIndicator: json["location_indicator"],
|
||||
opponent: json["opponent"],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum AthleticsEventLocation {
|
||||
home,
|
||||
away,
|
||||
neither,
|
||||
}
|
||||
|
||||
class ClpEvent implements Event {
|
||||
@override
|
||||
final String title;
|
||||
@override
|
||||
DateTime get time {
|
||||
return startTime;
|
||||
}
|
||||
@override
|
||||
final String location;
|
||||
@override
|
||||
final String category;
|
||||
|
||||
final DateTime startTime;
|
||||
final DateTime endTime;
|
||||
final String organization;
|
||||
final String description;
|
||||
|
||||
ClpEvent({
|
||||
required this.title,
|
||||
required this.startTime,
|
||||
required this.endTime,
|
||||
required this.location,
|
||||
required this.category,
|
||||
required this.organization,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
factory ClpEvent.fromJson(Map<String, dynamic> json) {
|
||||
return ClpEvent(
|
||||
title: json["title"],
|
||||
startTime: DateTime.parse(json["date"] + " " + json["start"]),
|
||||
endTime: DateTime.parse(json["date"] + " " + json["end"]),
|
||||
location: json["location"],
|
||||
category: json["eventType"],
|
||||
organization: json["organization"],
|
||||
description: json["description"],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
import 'dart:convert';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'dart:typed_data';
|
||||
import 'package:convert/convert.dart';
|
||||
import 'package:furman_now/secrets.dart';
|
||||
|
||||
class BarcodeService {
|
||||
static generateGetBarcode({ int? timestamp }) {
|
||||
// seconds since epoch
|
||||
timestamp ??= DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
|
||||
// final timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
// const timestamp = 1661567550;
|
||||
|
||||
final timestampBytes = _int64BigEndianBytes(timestamp);
|
||||
|
||||
const cbordKey = Secrets.cbordKey;
|
||||
const institutionKey = Secrets.institutionKey;
|
||||
const patronKey = Secrets.testPatronKey;
|
||||
|
||||
final cbordKeyBytes = Uint8List.fromList(hex.decode(utf8.decode(base64Decode(cbordKey))));
|
||||
final institutionKeyBytes = Uint8List.fromList(hex.decode(institutionKey));
|
||||
final patronKeyBytes = _int32LittleEndianBytes(patronKey);
|
||||
final sharedKeyBytes = _xorEncrypt(cbordKeyBytes, institutionKeyBytes);
|
||||
|
||||
final checksumDigit = _luhnGenerate(patronKey.toString());
|
||||
|
||||
// print(hex.encode(_int32BigEndianBytes(timestamp)));
|
||||
final barcodeOtc = int.parse(_hotp(sharedKeyBytes, timestampBytes, 9, hash: sha256));
|
||||
final barcodeOtcBytes = _int32LittleEndianBytes(barcodeOtc);
|
||||
|
||||
final encryptedBytes = _xorEncrypt(patronKeyBytes, barcodeOtcBytes);
|
||||
final encrypted = ByteData.view(encryptedBytes.buffer).getInt32(0, Endian.little);
|
||||
|
||||
final barcodeData = "${timestamp.toString().padLeft(10, "0")}1${encrypted.toString().padLeft(10, "0")}$checksumDigit";
|
||||
|
||||
return barcodeData;
|
||||
}
|
||||
|
||||
static int _luhnGenerate(String code) {
|
||||
const computed = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9];
|
||||
var sum = 0,
|
||||
digit = 0,
|
||||
i = code.length,
|
||||
even = false;
|
||||
|
||||
while (i-- > 0) {
|
||||
digit = int.parse(code[i]);
|
||||
sum += (even = !even) ? computed[digit] : digit;
|
||||
}
|
||||
|
||||
return (sum * 9) % 10;
|
||||
}
|
||||
|
||||
static Uint8List _xorEncrypt(List<int> subject, List<int> key) {
|
||||
var out = Uint8List(subject.length);
|
||||
for (int i = 0; i < subject.length; i++) {
|
||||
out[i] = subject[i] ^ key[i % key.length];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static _hotp(Uint8List key, Uint8List counter, int digits, { Hash hash = sha256 }) {
|
||||
final mac = Uint8List.fromList(Hmac(hash, key).convert(counter).bytes);
|
||||
final offset = mac[mac.length - 1] & 0x0f;
|
||||
final binary = ByteData.view(mac.buffer).getInt32(offset, Endian.big) & 0x7fffffff;
|
||||
var binaryString = binary.toString();
|
||||
if (binaryString.length - digits > 0) {
|
||||
binaryString = binaryString.substring(binaryString.length - digits);
|
||||
}
|
||||
binaryString = binaryString.padLeft(digits, "0");
|
||||
return binaryString;
|
||||
}
|
||||
|
||||
static Uint8List _int32LittleEndianBytes(int value) =>
|
||||
Uint8List(4)..buffer.asByteData().setInt32(0, value, Endian.little);
|
||||
|
||||
static Uint8List _int64BigEndianBytes(int value) {
|
||||
var sendValueBytes = ByteData(8);
|
||||
// setUint64 not implemented on some systems so use setUint32 in
|
||||
// those cases. Leading zeros to pad to equal 64 bit.
|
||||
// Epoch as 32-bit good until 2038 Jan 19 @ 03:14:07
|
||||
try {
|
||||
sendValueBytes.setUint64(0, value, Endian.big);
|
||||
} on UnsupportedError {
|
||||
sendValueBytes.setUint32(0, value, Endian.big);
|
||||
}
|
||||
return sendValueBytes.buffer.asUint8List();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import 'dart:io';
|
||||
|
||||
import "barcode_service.dart";
|
||||
|
||||
void main(List<String> args) {
|
||||
// while(true) {
|
||||
// print(BarcodeService.generateGetBarcode());
|
||||
// sleep(const Duration(seconds:1));
|
||||
// }
|
||||
|
||||
print(BarcodeService.generateGetBarcode(timestamp: int.parse(args[0])));
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
1661796958104839794376
|
||||
1661796959104317426886
|
||||
1661796960108255460226
|
||||
1661796961106920860666
|
||||
1661796962106199730706
|
||||
1661796963100729423146
|
||||
1661796964100826751576
|
||||
1661796965105980662356
|
||||
1661796966100792147766
|
||||
1661796967103886508706
|
||||
1661796968101562397906
|
||||
1661796969109347522246
|
||||
1661796970104476755206
|
||||
1661796971106085404376
|
||||
1661796972100553491616
|
||||
1661796973101404143146
|
||||
1661796974105377734796
|
||||
1661796975107065989056
|
||||
1661796976105135326536
|
||||
1661796977100360805266
|
||||
1661796978108364147506
|
||||
1661796979106002091456
|
||||
1661796980100164117926
|
||||
1661796981109290599786
|
||||
1661796982107498877976
|
||||
1661796983100444791306
|
||||
1661796984103380694806
|
||||
1661796985105701206076
|
||||
1661796986103876556676
|
||||
1661796987102846575686
|
||||
1661796988109894924956
|
||||
1661796989109869297986
|
||||
1661796990105289985306
|
||||
1661796991107971540556
|
||||
1661796992109255791256
|
||||
1661796993104515591796
|
||||
1661796994105087857776
|
||||
1661796995100628463616
|
||||
1661796996109645970966
|
||||
1661796997102192728376
|
||||
1661796998101976381966
|
||||
1661796999100836277786
|
||||
1661797000107503534346
|
||||
1661797001100639859056
|
||||
1661797002101528598866
|
||||
1661797003105623778966
|
||||
1661797004107907863076
|
||||
1661797005109315398796
|
||||
1661797006100768643546
|
||||
1661797007101212204946
|
||||
1661797008103273524436
|
||||
1661797009101866267696
|
||||
1661797010102857038416
|
||||
1661797011102685511796
|
||||
1661797012100193444876
|
||||
1661797013103722518116
|
||||
1661797014108411880946
|
||||
1661797015101560642386
|
||||
1661797016109488069706
|
||||
1661797017100723908746
|
||||
1661797018103949619536
|
||||
1661797019109992965496
|
||||
1661797020106962817906
|
||||
1661797021108226414706
|
||||
1661797022106594105606
|
||||
1661797023100233692336
|
|
@ -0,0 +1,3 @@
|
|||
class UserService {
|
||||
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/painting.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class RestaurantService {
|
||||
static Future<List<Restaurant>> fetchRestaurants() async {
|
||||
var restaurants = (await _fetchRestaurants()).toList();
|
||||
await _fetchRestaurantHours(restaurants);
|
||||
return restaurants;
|
||||
}
|
||||
|
||||
static Future<Iterable<Restaurant>> _fetchRestaurants() async {
|
||||
final response = await http
|
||||
.get(Uri.parse("https://cs.furman.edu/~csdaemon/FUNow/restaurantGet.php"));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// If the server did return a 200 OK response,
|
||||
// then parse the JSON.
|
||||
final restaurantsJson = jsonDecode(response.body);
|
||||
return (restaurantsJson["results"] as List<dynamic>).map((restaurant) =>
|
||||
Restaurant.fromJson(restaurant)
|
||||
);
|
||||
} else {
|
||||
// If the server did not return a 200 OK response,
|
||||
// then throw an exception.
|
||||
throw Exception('Failed to load athletics events.');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _fetchRestaurantHours(List<Restaurant> restaurants) async {
|
||||
final response = await http
|
||||
.get(Uri.parse("https://cs.furman.edu/~csdaemon/FUNow/restaurantHoursGet.php"));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// If the server did return a 200 OK response,
|
||||
// then parse the JSON.
|
||||
final hoursListJson = jsonDecode(response.body);
|
||||
for (var hoursJson in (hoursListJson["results"] as List<dynamic>)) {
|
||||
var hours = Hours.fromJson(hoursJson);
|
||||
restaurants.firstWhere((restaurant) => restaurant.id == hours.id).hoursList.add(hours);
|
||||
}
|
||||
} else {
|
||||
// If the server did not return a 200 OK response,
|
||||
// then throw an exception.
|
||||
throw Exception('Failed to load athletics events.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Restaurant {
|
||||
int id;
|
||||
String name;
|
||||
String? shortName;
|
||||
String location;
|
||||
LatLng mapLocation;
|
||||
int frequency;
|
||||
int busyness;
|
||||
String? url;
|
||||
List<Hours> hoursList = <Hours>[];
|
||||
|
||||
Restaurant({
|
||||
required this.id,
|
||||
required this.name,
|
||||
this.shortName,
|
||||
required this.location,
|
||||
required this.mapLocation,
|
||||
required this.frequency,
|
||||
required this.busyness,
|
||||
this.url,
|
||||
});
|
||||
|
||||
bool get isOpen {
|
||||
for(var hours in hoursList) {
|
||||
var now = DateTime.now();
|
||||
var today = Weekday.values[now.weekday - 1];
|
||||
if (hours.daysOfWeek.days[today] == true) {
|
||||
var currentTime = Duration(hours: now.hour, minutes: now.minute, seconds: now.second);
|
||||
if(hours.startTime != null && hours.endTime != null) {
|
||||
if (hours.startTime! < currentTime && hours.endTime! > currentTime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: this is the absolute worst
|
||||
String get imageUri {
|
||||
return "https://cs.furman.edu/~csdaemon/FUNow/appIcons/$name Icon.png";
|
||||
}
|
||||
|
||||
ImageProvider get image {
|
||||
return NetworkImage(imageUri);
|
||||
}
|
||||
|
||||
factory Restaurant.fromJson(Map<String, dynamic> json) {
|
||||
return Restaurant(
|
||||
id: int.parse(json["id"]),
|
||||
name: json["fullname"],
|
||||
shortName: json["name"],
|
||||
location: json["location"],
|
||||
mapLocation: LatLng(double.parse(json["latitude"]), double.parse(json["longitude"])),
|
||||
frequency: int.parse(json["frequency"]),
|
||||
busyness: int.parse(json["busyness"]),
|
||||
url: (json["url"] != null && (json["url"] as String).isNotEmpty) ? json["url"] : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Hours {
|
||||
int id;
|
||||
String? meal;
|
||||
Duration? startTime;
|
||||
Duration? endTime;
|
||||
DaysOfWeek daysOfWeek;
|
||||
int dayOrder;
|
||||
|
||||
Hours({
|
||||
required this.id,
|
||||
this.meal,
|
||||
this.startTime,
|
||||
this.endTime,
|
||||
required this.daysOfWeek,
|
||||
required this.dayOrder,
|
||||
});
|
||||
|
||||
static Duration _getDurationFromString(String s) {
|
||||
var timeComponents = s.split(":");
|
||||
var hours = int.parse(timeComponents[0]);
|
||||
var minutes = int.parse(timeComponents[1]);
|
||||
var seconds = int.parse(timeComponents[2]);
|
||||
|
||||
return Duration(hours: hours, minutes: minutes, seconds: seconds);
|
||||
}
|
||||
|
||||
factory Hours.fromJson(Map<String, dynamic> json) {
|
||||
return Hours(
|
||||
id: int.parse(json["id"]),
|
||||
meal: json["meal"],
|
||||
startTime: (json["start"] != null) ? _getDurationFromString(json["start"]) : null,
|
||||
endTime: (json["end"] != null) ? _getDurationFromString(json["end"]) : null,
|
||||
daysOfWeek: DaysOfWeek.parse(json["dayOfWeek"]),
|
||||
dayOrder: int.parse(json["dayOrder"]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DaysOfWeek {
|
||||
final Weekday startDay;
|
||||
final Weekday endDay;
|
||||
final Map<Weekday, bool> days;
|
||||
|
||||
DaysOfWeek({
|
||||
required this.startDay,
|
||||
required this.endDay,
|
||||
required this.days,
|
||||
});
|
||||
|
||||
static Weekday _getDayFromShortName(String shortName) {
|
||||
switch(shortName.toLowerCase()) {
|
||||
case "mon":
|
||||
return Weekday.monday;
|
||||
case "tue":
|
||||
return Weekday.tuesday;
|
||||
case "wed":
|
||||
return Weekday.wednesday;
|
||||
case "thu":
|
||||
return Weekday.thursday;
|
||||
case "fri":
|
||||
return Weekday.friday;
|
||||
case "sat":
|
||||
return Weekday.saturday;
|
||||
case "sun":
|
||||
return Weekday.sunday;
|
||||
default:
|
||||
throw "Invalid date short name.";
|
||||
}
|
||||
}
|
||||
|
||||
factory DaysOfWeek.parse(String s) {
|
||||
final Map<Weekday, bool> days = { for (var e in Weekday.values) e : false };
|
||||
|
||||
// single day
|
||||
if (!s.contains("-")) {
|
||||
var day = _getDayFromShortName(s);
|
||||
days.update(day, (val) => true);
|
||||
return DaysOfWeek(startDay: day, endDay: day, days: days);
|
||||
}
|
||||
|
||||
// date range
|
||||
var dayNames = s.split("-");
|
||||
final startDay = _getDayFromShortName(dayNames[0]);
|
||||
final endDay = _getDayFromShortName(dayNames[1]);
|
||||
int i = startDay.index;
|
||||
|
||||
// loop through to add all dates in date range to list
|
||||
while(i != endDay.index) {
|
||||
days.update(Weekday.values[i], (val) => true);
|
||||
|
||||
if (i < Weekday.values.length - 1) {
|
||||
i++;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
days.update(endDay, (val) => true);
|
||||
|
||||
return DaysOfWeek(
|
||||
startDay: startDay,
|
||||
endDay: endDay,
|
||||
days: days,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum Weekday {
|
||||
monday,
|
||||
tuesday,
|
||||
wednesday,
|
||||
thursday,
|
||||
friday,
|
||||
saturday,
|
||||
sunday,
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import "restaurant_service.dart";
|
||||
|
||||
void main() async {
|
||||
var restaurants = await RestaurantService.fetchRestaurants();
|
||||
for (var restaurant in restaurants) {
|
||||
print(restaurant.name + " " + (restaurant.isOpen ? "is open" : "is closed"));
|
||||
}
|
||||
// print("Start day: ${restaurants.firstWhere((restaurant) => restaurant.id == 22).hoursList[0].daysOfWeek.startDay}");
|
||||
// print("End day: ${restaurants.firstWhere((restaurant) => restaurant.id == 22).hoursList[0].daysOfWeek.endDay}");
|
||||
// print("Days of week: ${restaurants.firstWhere((restaurant) => restaurant.id == 22).hoursList[0].daysOfWeek.days}");
|
||||
|
||||
// var testRestaurant = Restaurant.fromJson(jsonDecode('''
|
||||
// {
|
||||
// "id":"10",
|
||||
// "name":null,
|
||||
// "fullname":"Papa John's Pizza",
|
||||
// "location":"Off Campus: 1507 Poinsett Hwy",
|
||||
// "latitude":"34.887977","longitude":"-82.405793",
|
||||
// "frequency":"10",
|
||||
// "busyness":"0",
|
||||
// "url":"https:\/\/www.papajohns.com\/order\/stores-near-me"
|
||||
// }
|
||||
// '''));
|
||||
|
||||
// var testDaysOfWeek = DaysOfWeek.parse("Sat-Mon");
|
||||
// print(testDaysOfWeek.days);
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
class TransportationBus503Service {
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
class TransportationSafeRideShuttleService {
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
class TransportationService {
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
DateTimeRange constructDateRange(DateTime startDateTime, DateTime endDateTime) {
|
||||
var startDate = DateTime(
|
||||
startDateTime.year,
|
||||
startDateTime.month,
|
||||
startDateTime.day,
|
||||
);
|
||||
var endDate = DateTime(
|
||||
endDateTime.year,
|
||||
endDateTime.month,
|
||||
endDateTime.day,
|
||||
23,
|
||||
59,
|
||||
59,
|
||||
);
|
||||
|
||||
return DateTimeRange(start: startDate, end: endDate);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
String greeting() {
|
||||
var currentHour = DateTime.now().hour;
|
||||
if (currentHour > 4 && currentHour < 11) {
|
||||
return "Good morning";
|
||||
} else if (currentHour >= 11 && currentHour < 17) {
|
||||
return "Good afternoon";
|
||||
} else if (currentHour >= 17 && currentHour < 21) {
|
||||
return "Good evening";
|
||||
} else {
|
||||
return "Good night";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
ThemeData _baseTheme = ThemeData(
|
||||
primarySwatch: Colors.deepPurple,
|
||||
bottomNavigationBarTheme: BottomNavigationBarThemeData(
|
||||
backgroundColor: Colors.grey[100],
|
||||
unselectedItemColor: Colors.grey[500],
|
||||
),
|
||||
textTheme: TextTheme(
|
||||
subtitle2: TextStyle(
|
||||
color: Colors.grey[500],
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
ThemeData myFurmanTheme = _baseTheme.copyWith(
|
||||
textTheme: GoogleFonts.interTextTheme(_baseTheme.textTheme),
|
||||
);
|
||||
|
||||
var furmanTextStyle = (TextStyle baseStyle) => GoogleFonts.inter(textStyle: baseStyle);
|
|
@ -0,0 +1,54 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
|
||||
class HeaderWidget extends StatelessWidget {
|
||||
const HeaderWidget({
|
||||
required this.title,
|
||||
this.link,
|
||||
Key? key
|
||||
}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
final HeaderLink? link;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(left: 40, right: 40, top: 20, bottom: 15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
title.toUpperCase(),
|
||||
style: furmanTextStyle(TextStyle(
|
||||
color: Colors.grey[800],
|
||||
fontWeight: FontWeight.w900,
|
||||
fontSize: 18,
|
||||
)),
|
||||
),
|
||||
if (link != null)
|
||||
Text(
|
||||
link!.text,
|
||||
style: furmanTextStyle(const TextStyle(
|
||||
color: Color(0xff755898),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@immutable
|
||||
class HeaderLink {
|
||||
final String text;
|
||||
final String href;
|
||||
|
||||
const HeaderLink({
|
||||
required this.text,
|
||||
required this.href,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/services/events/event.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class EventCard extends StatelessWidget {
|
||||
const EventCard
|
||||
(
|
||||
this.event,
|
||||
{
|
||||
Key? key
|
||||
}
|
||||
) : super(key: key);
|
||||
|
||||
final Event event;
|
||||
|
||||
String get eventHour {
|
||||
var formatter = DateFormat('hh:mm');
|
||||
return formatter.format(event.time);
|
||||
}
|
||||
|
||||
String get eventAmPm {
|
||||
var formatter = DateFormat('a');
|
||||
return formatter.format(event.time);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xfff9f9fb),
|
||||
borderRadius: BorderRadius.all(Radius.circular(10))
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(eventHour, style: furmanTextStyle(const TextStyle(fontWeight: FontWeight.w700))),
|
||||
Text(eventAmPm, style: Theme.of(context).textTheme.subtitle2),
|
||||
],
|
||||
),
|
||||
),
|
||||
VerticalDivider(
|
||||
width: 2,
|
||||
thickness: 2,
|
||||
color: Colors.grey[200],
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(event.title, style: furmanTextStyle(const TextStyle(fontWeight: FontWeight.w600))),
|
||||
const SizedBox(height: 6),
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 5.0),
|
||||
child: Icon(Icons.place_outlined, size: 20, color: Colors.grey[500])
|
||||
),
|
||||
),
|
||||
TextSpan(text: event.location),
|
||||
],
|
||||
)),
|
||||
const SizedBox(height: 2),
|
||||
RichText(text: TextSpan(
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 1.0, right: 6.0),
|
||||
child: Icon(Icons.sell_outlined, size: 18, color: Colors.grey[500])
|
||||
),
|
||||
),
|
||||
TextSpan(text: event.category),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/services/events/event.dart';
|
||||
import 'package:furman_now/src/services/events/events_service.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
|
||||
import 'event_card.dart';
|
||||
|
||||
class EventsList extends StatefulWidget {
|
||||
final DateTimeRange dateRange;
|
||||
|
||||
const EventsList._({
|
||||
required this.dateRange,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
factory EventsList({
|
||||
DateTimeRange? dateRange,
|
||||
Key? key,
|
||||
}) {
|
||||
if (dateRange == null) {
|
||||
final now = DateTime.now();
|
||||
final today = DateTime(now.year, now.month, now.day);
|
||||
final tonight = DateTime(now.year, now.month, now.day, 23, 59, 59);
|
||||
dateRange = DateTimeRange(start: today, end: tonight);
|
||||
}
|
||||
return EventsList._(
|
||||
dateRange: dateRange,
|
||||
key: key,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
State<EventsList> createState() => _EventsListState();
|
||||
}
|
||||
|
||||
class _EventsListState extends State<EventsList> {
|
||||
late Future<Iterable<Event>> futureEventList;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
futureEventList = EventsService.fetchEvents();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<Iterable<Event>>(
|
||||
future: futureEventList,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var events = snapshot.data!.where((event) {
|
||||
return event.time.isAfter(widget.dateRange.start) && event.time.isBefore(widget.dateRange.end);
|
||||
});
|
||||
if (events.isNotEmpty) {
|
||||
return Column(
|
||||
children: events.map((event) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 15),
|
||||
child: EventCard(event),
|
||||
);
|
||||
}).toList());
|
||||
} else {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 15),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: 50,
|
||||
child: Center(
|
||||
child: Text(
|
||||
"No events today :(",
|
||||
style: furmanTextStyle(TextStyle(
|
||||
color: Colors.grey[600],
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else if (snapshot.hasError) {
|
||||
return Text('${snapshot.error}', style: const TextStyle(color: Colors.red),);
|
||||
}
|
||||
|
||||
// By default, show a loading spinner.
|
||||
return const Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 25),
|
||||
child: CircularProgressIndicator()
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:palette_generator/palette_generator.dart';
|
||||
import 'package:furman_now/src/services/restaurants/restaurant_service.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
|
||||
class RestaurantCard extends StatefulWidget {
|
||||
const RestaurantCard({
|
||||
required this.restaurant,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
final Restaurant restaurant;
|
||||
|
||||
@override
|
||||
State<RestaurantCard> createState() => _RestaurantCardState();
|
||||
}
|
||||
|
||||
class _RestaurantCardState extends State<RestaurantCard> {
|
||||
PaletteGenerator? paletteGenerator;
|
||||
Color? backgroundColor;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_updatePaletteGenerator();
|
||||
}
|
||||
|
||||
Future<void> _updatePaletteGenerator() async {
|
||||
paletteGenerator = await PaletteGenerator.fromImageProvider(
|
||||
widget.restaurant.image,
|
||||
maximumColorCount: 1,
|
||||
);
|
||||
if (paletteGenerator != null && paletteGenerator!.colors.toList().isNotEmpty) {
|
||||
var hslColor = HSLColor.fromColor(paletteGenerator!.colors.toList()[0]);
|
||||
var newColor = HSLColor.fromAHSL(1, hslColor.hue, 40/100, 90/100);
|
||||
backgroundColor = newColor.toColor();
|
||||
}
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: 150,
|
||||
height: 175,
|
||||
decoration: BoxDecoration(
|
||||
// color: Color(0xfff9f9fb),
|
||||
color: backgroundColor ?? const Color(0xfff9f9fb),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Column(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
style: furmanTextStyle(TextStyle(
|
||||
color: Colors.grey[800],
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
)),
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 4),
|
||||
child: Container(
|
||||
width: 9,
|
||||
height: 9,
|
||||
decoration: BoxDecoration(
|
||||
color: widget.restaurant.isOpen ? Colors.green : Colors.red.shade700,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
TextSpan(text: widget.restaurant.isOpen ? "Open" : "Closed"),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(5)),
|
||||
child: Image.network(widget.restaurant.imageUri, height: 90),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Text(
|
||||
widget.restaurant.name,
|
||||
textAlign: TextAlign.center,
|
||||
style: furmanTextStyle(TextStyle(
|
||||
color: Colors.grey[800],
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/services/restaurants/restaurant_service.dart';
|
||||
|
||||
import 'restaurant_card.dart';
|
||||
|
||||
class RestaurantsList extends StatefulWidget {
|
||||
const RestaurantsList({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<RestaurantsList> createState() => _RestaurantsListState();
|
||||
}
|
||||
|
||||
class _RestaurantsListState extends State<RestaurantsList> {
|
||||
late Future<List<Restaurant>> futureEventList;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
futureEventList = RestaurantService.fetchRestaurants();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<List<Restaurant>>(
|
||||
future: futureEventList,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var restaurants = snapshot.data!..sort((r1, r2) => (r1.isOpen ? 0 : 1) - (r2.isOpen ? 0 : 1));
|
||||
return SizedBox(
|
||||
height: 175,
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.only(left: 20),
|
||||
itemCount: restaurants.length,
|
||||
cacheExtent: 10000,
|
||||
scrollDirection: Axis.horizontal,
|
||||
prototypeItem: Padding(
|
||||
padding: const EdgeInsets.only(right: 15),
|
||||
child: RestaurantCard(restaurant: restaurants.first),
|
||||
),
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: const EdgeInsets.only(right: 15),
|
||||
child: RestaurantCard(restaurant: restaurants[index]),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Text('${snapshot.error}', style: const TextStyle(color: Colors.red))
|
||||
);
|
||||
}
|
||||
|
||||
// By default, show a loading spinner.
|
||||
return const Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 25),
|
||||
child: CircularProgressIndicator()
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:furman_now/src/utils/theme.dart';
|
||||
|
||||
class TransportationCard extends StatelessWidget {
|
||||
const TransportationCard({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xfff9f9fb),
|
||||
borderRadius: BorderRadius.all(Radius.circular(10))
|
||||
),
|
||||
child: IntrinsicHeight(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 75,
|
||||
child: Icon(Icons.directions_bus, size: 50, color: Colors.grey[800]),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
style: furmanTextStyle(TextStyle(
|
||||
color: Colors.grey[800],
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
)),
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 4),
|
||||
child: Container(
|
||||
width: 9,
|
||||
height: 9,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.green,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const TextSpan(text: "Running"),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
"503 Bus",
|
||||
style: furmanTextStyle(TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey[800],
|
||||
fontSize: 18,
|
||||
)),
|
||||
),
|
||||
Text(
|
||||
"Next stop: Pointsett Hwy & Crestwood Dr",
|
||||
style: furmanTextStyle(TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey[500],
|
||||
fontSize: 12,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class InfoCard extends StatelessWidget {
|
||||
final Color color;
|
||||
final IconData icon;
|
||||
final String title;
|
||||
final String description;
|
||||
|
||||
const InfoCard({
|
||||
required this.color,
|
||||
required this.icon,
|
||||
required this.title,
|
||||
required this.description,
|
||||
Key? key
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 15, right: 5),
|
||||
child: Icon(icon, size: 40,)
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(title, style: Theme.of(context).textTheme.titleLarge,),
|
||||
Text(description),
|
||||
]
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|