diff options
author | Marvin Borner | 2018-07-20 13:35:01 +0200 |
---|---|---|
committer | Marvin Borner | 2018-07-20 13:35:01 +0200 |
commit | 18b8bd888a13c6dadfb7961cc88214332b6f5d38 (patch) | |
tree | d612ebe36e8211ffd74b2ead56e07600a98bfe5f | |
parent | a5f5deac3f5bed6beee343df237c74294766426e (diff) |
Began basic chat interface
-rw-r--r-- | .gitignore | 11 | ||||
-rw-r--r-- | BEAM_Messenger.iml | 15 | ||||
-rw-r--r-- | android.iml | 12 | ||||
-rw-r--r-- | android/.gitignore | 13 | ||||
-rw-r--r-- | android/app/build.gradle | 54 | ||||
-rw-r--r-- | android/app/src/main/AndroidManifest.xml | 32 | ||||
-rw-r--r-- | android/app/src/main/java/de/beam_messenger/BEAM_Messenger/MainActivity.java | 14 | ||||
-rw-r--r-- | android/app/src/main/res/mipmap-hdpi/ic_launcher.png | bin | 0 -> 544 bytes | |||
-rw-r--r-- | android/app/src/main/res/mipmap-mdpi/ic_launcher.png | bin | 0 -> 442 bytes | |||
-rw-r--r-- | android/app/src/main/res/mipmap-xhdpi/ic_launcher.png | bin | 0 -> 721 bytes | |||
-rw-r--r-- | android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png | bin | 0 -> 1031 bytes | |||
-rw-r--r-- | android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png | bin | 0 -> 1443 bytes | |||
-rw-r--r-- | android/build.gradle | 35 | ||||
-rw-r--r-- | android/gradle.properties | 1 | ||||
-rw-r--r-- | android/settings.gradle | 15 | ||||
-rw-r--r-- | lib/main.dart | 181 | ||||
-rw-r--r-- | pubspec.yaml | 51 |
17 files changed, 434 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b047393 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +.DS_Store +.atom/ +.idea +.vscode/ +.packages +.pub/ +build/ +ios/ +packages +pubspec.lock +.flutter-plugins diff --git a/BEAM_Messenger.iml b/BEAM_Messenger.iml new file mode 100644 index 0000000..9d5dae1 --- /dev/null +++ b/BEAM_Messenger.iml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="FLUTTER_MODULE_TYPE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <excludeFolder url="file://$MODULE_DIR$/.idea" /> + <excludeFolder url="file://$MODULE_DIR$/.pub" /> + <excludeFolder url="file://$MODULE_DIR$/build" /> + <excludeFolder url="file://$MODULE_DIR$/packages" /> + </content> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="library" name="Dart Packages" level="project" /> + <orderEntry type="library" name="Dart SDK" level="project" /> + </component> +</module>
\ No newline at end of file diff --git a/android.iml b/android.iml new file mode 100644 index 0000000..faad093 --- /dev/null +++ b/android.iml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$/android"> + <sourceFolder url="file://$MODULE_DIR$/android/app/src/main/java" isTestSource="false" /> + </content> + <orderEntry type="jdk" jdkName="Android API 26 Platform" jdkType="Android SDK" /> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="library" name="Flutter for Android" level="project" /> + </component> +</module> diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..1fd9325 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,13 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +GeneratedPluginRegistrant.java + +/gradle +/gradlew +/gradlew.bat diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..0fa8004 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,54 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withInputStream { stream -> + localProperties.load(stream) + } +} + +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.") +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 26 + buildToolsVersion '26.0.2' + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "de.beam_messenger.BEAM_Messenger" + } + + buildTypes { + debug { + applicationIdSuffix '.debug' + versionNameSuffix '-DEBUG' + } + + 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 { + androidTestCompile 'com.android.support:support-annotations:25.0.0' + androidTestCompile 'com.android.support.test:runner:0.5' + androidTestCompile 'com.android.support.test:rules:0.5' +}
\ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..1cae011 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,32 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="de.beam_messenger.BEAM_Messenger" + android:versionCode="1" + android:versionName="0.0.1"> + + <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" /> + + <!-- The INTERNET permission is required for development. Specifically, + flutter needs it to communicate with the running application + to allow setting breakpoints, to provide hot reload, etc. + --> + <uses-permission android:name="android.permission.INTERNET"/> + + <!-- io.flutter.app.FlutterApplication is an android.app.Application that + calls FlutterMain.startInitialization(this); in its onCreate method. + In most cases you can leave this as-is, but you if you want to provide + additional functionality it is fine to subclass or reimplement + FlutterApplication and put your custom class here. --> + <application android:name="io.flutter.app.FlutterApplication" android:label="BEAM-Messenger" android:icon="@mipmap/ic_launcher"> + <activity android:name=".MainActivity" + android:launchMode="singleTop" + android:theme="@android:style/Theme.Black.NoTitleBar" + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection" + android:hardwareAccelerated="true" + android:windowSoftInputMode="adjustResize"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/android/app/src/main/java/de/beam_messenger/BEAM_Messenger/MainActivity.java b/android/app/src/main/java/de/beam_messenger/BEAM_Messenger/MainActivity.java new file mode 100644 index 0000000..bdf997d --- /dev/null +++ b/android/app/src/main/java/de/beam_messenger/BEAM_Messenger/MainActivity.java @@ -0,0 +1,14 @@ +package de.beam_messenger.BEAM_Messenger; + +import android.os.Bundle; + +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..db77bb4 --- /dev/null +++ b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..17987b7 --- /dev/null +++ b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..09d4391 --- /dev/null +++ b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..d5f1c8d --- /dev/null +++ b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..4d6372e --- /dev/null +++ b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..60b1490 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,35 @@ +buildscript { + repositories { + jcenter() + maven { + url "https://maven.google.com" + } + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.0.1' + } +} + +allprojects { + repositories { + jcenter() + maven { + url "https://maven.google.com" + } + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} + +task wrapper(type: Wrapper) { + gradleVersion = '2.14.1' +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..8bd86f6 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..115da6c --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withInputStream { stream -> plugins.load(stream) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..d20cde4 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,181 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +void main() { + runApp(new MessengerApp()); +} + +final ThemeData kIOSTheme = new ThemeData( + primarySwatch: Colors.orange, + primaryColor: Colors.grey[100], + primaryColorBrightness: Brightness.light, +); + +final ThemeData kDefaultTheme = new ThemeData( + primarySwatch: Colors.blue, + accentColor: Colors.orangeAccent[400], +); + +const String _name = "Marvin Borner"; + +class MessengerApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return new MaterialApp( + title: "BEAM-Messenger", + theme: defaultTargetPlatform == TargetPlatform.iOS + ? kIOSTheme + : kDefaultTheme, + home: new ChatScreen(), + ); + } +} + +class ChatMessage extends StatelessWidget { + ChatMessage({this.text, this.animationController}); + final String text; + final AnimationController animationController; + @override + Widget build(BuildContext context) { + return new SizeTransition( + sizeFactor: new CurvedAnimation( + parent: animationController, + curve: Curves.easeOut + ), + axisAlignment: 0.0, + child: new Container( + margin: const EdgeInsets.symmetric(vertical: 10.0), + child: new Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: <Widget>[ + new Container( + margin: const EdgeInsets.only(right: 16.0), + child: new CircleAvatar(child: new Text(_name[0])), + ), + new Expanded( + child: new Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: <Widget>[ + new Text(_name, style: Theme.of(context).textTheme.subhead), + new Container( + margin: const EdgeInsets.only(top: 5.0), + child: new Text(text), + ), + ], + ), + ), + ], + ), + ) + ); + } +} + +class ChatScreen extends StatefulWidget { + @override + State createState() => new ChatScreenState(); +} + +class ChatScreenState extends State<ChatScreen> with TickerProviderStateMixin { + final List<ChatMessage> _messages = <ChatMessage>[]; + final TextEditingController _textController = new TextEditingController(); + bool _isComposing = false; + + void _handleSubmitted(String text) { + _textController.clear(); + setState(() { + _isComposing = false; + }); + ChatMessage message = new ChatMessage( + text: text, + animationController: new AnimationController( + duration: new Duration(milliseconds: 700), + vsync: this, + ), + ); + setState(() { + _messages.insert(0, message); + }); + message.animationController.forward(); + } + + void dispose() { + for (ChatMessage message in _messages) + message.animationController.dispose(); + super.dispose(); + } + + Widget _buildTextComposer() { + return new IconTheme( + data: new IconThemeData(color: Theme.of(context).accentColor), + child: new Container( + margin: const EdgeInsets.symmetric(horizontal: 8.0), + child: new Row(children: <Widget>[ + new Flexible( + child: new TextField( + controller: _textController, + onChanged: (String text) { + setState(() { + _isComposing = text.length > 0; + }); + }, + onSubmitted: _handleSubmitted, + decoration: + new InputDecoration.collapsed(hintText: "Send a message..."), + ), + ), + new Container( + margin: new EdgeInsets.symmetric(horizontal: 4.0), + child: Theme.of(context).platform == TargetPlatform.iOS + ? new CupertinoButton( + child: new Text("Send"), + onPressed: _isComposing + ? () => _handleSubmitted(_textController.text) + : null, + ) + : new IconButton( + icon: new Icon(Icons.send), + onPressed: _isComposing + ? () => _handleSubmitted(_textController.text) + : null, + )), + ]), + decoration: Theme.of(context).platform == TargetPlatform.iOS + ? new BoxDecoration( + border: + new Border(top: new BorderSide(color: Colors.grey[200]))) + : null), + ); + } + + Widget build(BuildContext context) { + return new Scaffold( + appBar: new AppBar( + title: new Text("BEAM-Messenger"), + elevation: + Theme.of(context).platform == TargetPlatform.iOS ? 0.0 : 4.0 + ), + body: new Container( + child: new Column( + children: <Widget>[ + new Flexible( + child: new ListView.builder( + padding: new EdgeInsets.all(8.0), + reverse: true, + itemBuilder: (_, int index) => _messages[index], + itemCount: _messages.length, + ) + ), + new Divider(height: 1.0), + new Container( + decoration: new BoxDecoration( + color: Theme.of(context).cardColor), + child: _buildTextComposer(), + ), + ] + ), + decoration: Theme.of(context).platform == TargetPlatform.iOS ? new BoxDecoration(border: new Border(top: new BorderSide(color: Colors.grey[200]))) : null), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..e1a823b --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,51 @@ +name: BEAM_Messenger +description: A new flutter project. + +dependencies: + flutter: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section here, in + # this "flutter" section, as in: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # To add assets from package dependencies, first ensure the asset + # is in the lib/ directory of the dependency. Then, + # refer to the asset with a path prefixed with + # `packages/PACKAGE_NAME/`. Note: the `lib/` is implied, do not + # include `lib/` in the asset path. + # + # Here is an example: + # + # assets: + # - packages/PACKAGE_NAME/path/to/asset + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 |