diff --git a/lib/chat_page.dart b/lib/chat_page.dart new file mode 100755 index 0000000..fde38f7 --- /dev/null +++ b/lib/chat_page.dart @@ -0,0 +1,146 @@ +import 'package:flutter/material.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Chats', + theme: ThemeData( + primarySwatch: Colors.green, + ), + home: const ChatScreen(), + ); + } +} + +class ChatScreen extends StatefulWidget { + @override + _ChatScreenState createState() => _ChatScreenState(); + const ChatScreen({super.key}); +} + +class _Message { + final String text; + final bool isMine; + final DateTime timestamp; + + _Message({required this.text, required this.isMine, required this.timestamp}); +} + +class _ChatScreenState extends State { + final TextEditingController _messageController = TextEditingController(); + final List<_Message> _messages = []; + + void _handleSendMessage() { + if (_messageController.text.isNotEmpty) { + setState(() { + _messages.add(_Message( + text: _messageController.text, + isMine: true, + timestamp: DateTime.now(), + )); + _messageController.clear(); + }); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Chats'), + centerTitle: true, + ), + body: Column( + children: [ + Expanded( + child: ListView.builder( + itemCount: _messages.length, + itemBuilder: (context, index) { + final isMine = _messages[index].isMine; + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0), + child: Row( + mainAxisAlignment: isMine ? MainAxisAlignment.end : MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (!isMine) + const Padding( + padding: EdgeInsets.only(right: 8), + child: Text( + 'Partner:', + style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold), + ), + ), + Column( + crossAxisAlignment: isMine ? CrossAxisAlignment.end : CrossAxisAlignment.start, + children: [ + Container( + decoration: BoxDecoration( + color: isMine ? Colors.blue : Colors.green, + borderRadius: BorderRadius.circular(10), + ), + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12), + child: Text( + _messages[index].text, + style: const TextStyle(color: Colors.white), + ), + ), + const SizedBox(height: 5), + Text( + '${_messages[index].timestamp.hour.toString().padLeft(2, '0')}:${_messages[index].timestamp.minute.toString().padLeft(2, '0')}', + style: const TextStyle(fontSize: 10, color: Colors.black), + ), + ], + ), + if (isMine) + const Padding( + padding: EdgeInsets.only(left: 8), + child: Text( + 'Me', + style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold), + ), + ), + ], + ), + ); + }, + ), + ), + const Divider(), + Container( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Expanded( + child: TextField( + controller: _messageController, + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: 'Type a message...', + ), + ), + ), + const SizedBox(width: 8), + FloatingActionButton( + onPressed: _handleSendMessage, + tooltip: 'Send', + splashColor: Colors.green, + backgroundColor: Colors.green, + hoverColor: Colors.pink, + child: const Icon(Icons.send_rounded), + ), + ], + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/inbox.dart b/lib/inbox.dart new file mode 100755 index 0000000..e5b0987 --- /dev/null +++ b/lib/inbox.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_animate/flutter_animate.dart'; + +class NotificationsPage extends StatelessWidget { + const NotificationsPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Center( + child: const Text('Inbox', style: TextStyle(fontSize: 24)).animate().fade().scale().tint(color: Colors.pink), + ), + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 7d746ec..9cf8428 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,25 +1,28 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'note_page.dart'; -import 'search_page.dart'; -import 'notifications_page.dart'; +import 'chat_page.dart'; +import 'inbox.dart'; import 'settings_page.dart'; void main() { - runApp(MyApp()); + runApp(const MyApp()); } class MyApp extends StatefulWidget { + const MyApp({super.key}); + @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { int _selectedIndex = 0; - static List _widgetOptions = [ - NotePage(), - SearchPage(), - NotificationsPage(), - SettingsPage(), + static final List _widgetOptions = [ + const NotePage(), + const ChatScreen(), + const NotificationsPage(), + const SettingsPage(), ]; void _onItemTapped(int index) { @@ -40,26 +43,28 @@ class _MyAppState extends State { bottomNavigationBar: BottomNavigationBar( items: const [ BottomNavigationBarItem( - icon: Icon(Icons.home), + icon: FaIcon(FontAwesomeIcons.house), label: 'Home', ), BottomNavigationBarItem( - icon: Icon(Icons.search), - label: 'Search', + icon: FaIcon(FontAwesomeIcons.solidMessage), + label: 'Chats', ), BottomNavigationBarItem( - icon: Icon(Icons.notifications), - label: 'Notifications', + icon: FaIcon(FontAwesomeIcons.solidBell), + label: 'Inbox', ), BottomNavigationBarItem( - icon: Icon(Icons.settings), + icon: FaIcon(FontAwesomeIcons.gear), label: 'Settings', ), ], - currentIndex: _selectedIndex, - unselectedItemColor: Colors.black, - selectedItemColor: Colors.pink, onTap: _onItemTapped, + currentIndex: _selectedIndex, + selectedItemColor: Colors.green, + unselectedItemColor: Colors.grey, + unselectedFontSize: 9.0, + showUnselectedLabels: true, ), ), debugShowCheckedModeBanner: false, diff --git a/lib/note_page.dart b/lib/note_page.dart index 27b50e2..b4a6d14 100755 --- a/lib/note_page.dart +++ b/lib/note_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'dart:math'; @@ -26,9 +27,9 @@ class Note { final String channel; final DateTime timestamp; final Color color; - int score; // Score attribute + int karma; - Note(this.content, this.channel, this.color, {this.score = 0}) : timestamp = DateTime.now(); + Note(this.content, this.channel, this.color, {this.karma = 0}) : timestamp = DateTime.now(); } class NotePage extends StatefulWidget { @@ -62,22 +63,22 @@ class _NotePageState extends State { mainAxisSize: MainAxisSize.min, // Limits the column's height expansion children: [ ConstrainedBox( - constraints: BoxConstraints(minHeight: 60), + constraints: const BoxConstraints(minHeight: 60), child: TextField( controller: channelController, - decoration: InputDecoration( + decoration: const InputDecoration( hintText: '@Channel', contentPadding: EdgeInsets.symmetric(vertical: 15.0), ), ), ), - SizedBox(height: 8), + const SizedBox(height: 8), ConstrainedBox( - constraints: BoxConstraints(minHeight: 60), + constraints: const BoxConstraints(minHeight: 60), child: TextField( controller: contentController, autofocus: true, - decoration: InputDecoration( + decoration: const InputDecoration( hintText: '#GoodVibesOnly', contentPadding: EdgeInsets.symmetric(vertical: 15.0), ), @@ -88,7 +89,7 @@ class _NotePageState extends State { actions: [ TextButton( onPressed: () => Navigator.pop(context, false), - child: const Text('Abbrechen'), + child: const Text('Cancel'), ), TextButton( onPressed: () { @@ -96,7 +97,7 @@ class _NotePageState extends State { Navigator.pop(context, true); } }, - child: const Text('Speichern'), + child: const Text('Save'), ), ], ); @@ -106,20 +107,20 @@ class _NotePageState extends State { if (saved == true) { setState(() { _notes.add( - Note(contentController.text, channelController.text, _colors[_random.nextInt(_colors.length)], score: 0)); + Note(contentController.text, channelController.text, _colors[_random.nextInt(_colors.length)], karma: 0)); }); } } - void incrementScore(int index) { + void incrementKarma(int index) { setState(() { - _notes[index].score++; + _notes[index].karma++; }); } - void decrementScore(int index) { + void decrementKarma(int index) { setState(() { - _notes[index].score--; + _notes[index].karma--; }); } @@ -128,16 +129,16 @@ class _NotePageState extends State { context: context, builder: (BuildContext context) { return AlertDialog( - title: const Text('Löschen bestätigen'), - content: const Text('Sicher, dass Sie "ihren" Jodel löschen möchten?'), + title: const Text('Confirm deletion'), + content: const Text('Are you sure you want to delete ‘your’ Jodel?'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), - child: const Text('Abbruch'), + child: const Text('Cancel'), ), TextButton( onPressed: () => Navigator.pop(context, true), - child: const Text('Löschen'), + child: const Text('Confirm'), ), ], ); @@ -167,25 +168,33 @@ class _NotePageState extends State { borderRadius: BorderRadius.circular(10.0), ), child: ListTile( - leading: Text(DateFormat('kk:mm:ss\nUTC+2') - .format(_notes[index].timestamp)), - title: Text(_notes[index].channel), - subtitle: Text(_notes[index].content), + title: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text("@${_notes[index].channel}", style: const TextStyle(fontSize: 15, color: Colors.black)), + const SizedBox(width: 10), + Text(DateFormat('kk:mm:ss').format(_notes[index].timestamp), style: const TextStyle(fontSize: 13, color: Colors.black)), + ], + ), + subtitle: Text(_notes[index].content, style: const TextStyle(fontSize: 20, color: Colors.white)), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( - icon: const Icon(Icons.arrow_upward), - onPressed: () => incrementScore(index), + icon: const FaIcon(FontAwesomeIcons.angleUp), + onPressed: () => incrementKarma(index), + color: Colors.black, ), - Text('${_notes[index].score}'), + Text('${_notes[index].karma}', style: const TextStyle(fontSize: 12, color: Colors.black)), IconButton( - icon: const Icon(Icons.arrow_downward), - onPressed: () => decrementScore(index), + icon: const FaIcon(FontAwesomeIcons.angleDown), + onPressed: () => decrementKarma(index), + color: Colors.black, ), IconButton( icon: const Icon(Icons.delete), onPressed: () => _removeNote(index), + color: Colors.red, ), ], ), @@ -199,8 +208,8 @@ class _NotePageState extends State { backgroundColor: Colors.green, hoverColor: Colors.pink, onPressed: _showAddNoteDialog, - tooltip: 'Neuer Jodel', - child: const Icon(Icons.add), + tooltip: 'New Jodel', + child: const FaIcon(FontAwesomeIcons.plus), ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, ); diff --git a/lib/notifications_page.dart b/lib/notifications_page.dart deleted file mode 100755 index 1c969e1..0000000 --- a/lib/notifications_page.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class NotificationsPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Text('Notifications Page', style: TextStyle(fontSize: 24, color: Colors.black)), - ), - ); - } -} diff --git a/lib/search_page.dart b/lib/search_page.dart deleted file mode 100755 index bb45594..0000000 --- a/lib/search_page.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class SearchPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Text('Search Page', style: TextStyle(fontSize: 24, color: Colors.black)), - ), - ); - } -} diff --git a/lib/settings_page.dart b/lib/settings_page.dart index 01e4429..25ecc03 100755 --- a/lib/settings_page.dart +++ b/lib/settings_page.dart @@ -1,11 +1,62 @@ import 'package:flutter/material.dart'; -class SettingsPage extends StatelessWidget { +class SettingsPage extends StatefulWidget { + @override + _SettingsPageState createState() => _SettingsPageState(); + const SettingsPage({super.key}); +} + +class _SettingsPageState extends State { + bool _darkMode = false; + bool _notificationsEnabled = true; + @override Widget build(BuildContext context) { return Scaffold( - body: Center( - child: Text('Settings Page', style: TextStyle(fontSize: 24, color: Colors.black)), + appBar: AppBar( + title: Text('Settings'), + ), + body: ListView( + children: [ + ListTile( + title: Text('Dark Mode'), + trailing: Switch( + value: _darkMode, + onChanged: (value) { + setState(() { + _darkMode = value; + }); + }, + ), + ), + ListTile( + title: Text('Notifications'), + trailing: Switch( + value: _notificationsEnabled, + onChanged: (value) { + setState(() { + _notificationsEnabled = value; + }); + }, + ), + ), + ListTile( + title: Text('Language'), + subtitle: Text('English'), + trailing: Icon(Icons.arrow_forward_ios), + onTap: () { + // Navigate to language selection page + }, + ), + ListTile( + title: Text('About'), + subtitle: Text('Version 1.0'), + trailing: Icon(Icons.info), + onTap: () { + // Show about dialog + }, + ), + ], ), ); } diff --git a/pubspec.lock b/pubspec.lock index 679c1aa..c760a7e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -62,6 +62,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_animate: + dependency: "direct main" + description: + name: flutter_animate + sha256: "7c8a6594a9252dad30cc2ef16e33270b6248c4dedc3b3d06c86c4f3f4dc05ae5" + url: "https://pub.dev" + source: hosted + version: "4.5.0" flutter_lints: dependency: "direct dev" description: @@ -70,11 +78,27 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + flutter_shaders: + dependency: transitive + description: + name: flutter_shaders + sha256: "02750b545c01ff4d8e9bbe8f27a7731aa3778402506c67daa1de7f5fc3f4befe" + url: "https://pub.dev" + source: hosted + version: "0.1.2" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + font_awesome_flutter: + dependency: "direct main" + description: + name: font_awesome_flutter + sha256: "275ff26905134bcb59417cf60ad979136f1f8257f2f449914b2c3e05bbb4cd6f" + url: "https://pub.dev" + source: hosted + version: "10.7.0" intl: dependency: "direct main" description: @@ -218,3 +242,4 @@ packages: version: "13.0.0" sdks: dart: ">=3.3.4 <4.0.0" + flutter: ">=3.7.0-0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 1860d54..ac8c78f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -27,14 +27,13 @@ environment: # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. + dependencies: flutter: sdk: flutter intl: ^0.19.0 - - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. + font_awesome_flutter: ^10.7.0 + flutter_animate: ^4.5.0 cupertino_icons: ^1.0.6 dev_dependencies: