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),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|