diff --git a/.metadata b/.metadata index 62246d65..bd61a635 100644 --- a/.metadata +++ b/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled. version: - revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 + revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b channel: beta project_type: app @@ -13,26 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 - base_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 + create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b + base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - platform: android - create_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 - base_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 + create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b + base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - platform: ios - create_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 - base_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 + create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b + base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - platform: linux - create_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 - base_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 + create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b + base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - platform: macos - create_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 - base_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 + create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b + base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - platform: web - create_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 - base_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 + create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b + base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b - platform: windows - create_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 - base_revision: ecdb7841df7de82e8c1abf6d98db25f160e7fde4 + create_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b + base_revision: 74e4b092e5212ebf8292dde2a48d3da960c0920b # User provided section diff --git a/android/app/src/main/kotlin/app/dungeon_paper/MainActivity.kt b/android/app/src/main/kotlin/app/dungeon_paper/MainActivity.kt index c2ff4ba7..8d8c3202 100644 --- a/android/app/src/main/kotlin/app/dungeon_paper/MainActivity.kt +++ b/android/app/src/main/kotlin/app/dungeon_paper/MainActivity.kt @@ -1,13 +1,6 @@ -package app.dungeonpaper +package app.dungeon_paper -import android.os.Bundle - -import io.flutter.app.FlutterActivity -import io.flutter.plugins.GeneratedPluginRegistrant +import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - GeneratedPluginRegistrant.registerWith(this) - } } diff --git a/android/app/src/main/kotlin/app/dungeon_paper_app/MainActivity.kt b/android/app/src/main/kotlin/app/dungeon_paper_app/MainActivity.kt deleted file mode 100644 index ccfea133..00000000 --- a/android/app/src/main/kotlin/app/dungeon_paper_app/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package app.dungeon_paper_app - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/android/app/src/main/kotlin/app/dungeonpaper/MainActivity.kt b/android/app/src/main/kotlin/app/dungeonpaper/MainActivity.kt deleted file mode 100644 index 07559099..00000000 --- a/android/app/src/main/kotlin/app/dungeonpaper/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package app.dungeonpaper - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/lib/app/data/models/campaign.dart b/lib/app/data/models/campaign.dart index 09512d8f..c6e5f93b 100644 --- a/lib/app/data/models/campaign.dart +++ b/lib/app/data/models/campaign.dart @@ -90,7 +90,9 @@ class Campaign with WithIcon implements WithMeta { String get displayName => name; @override - IconData get icon => Icons.groups; + IconData get icon => genericIcon; + + static IconData get genericIcon => Icons.groups; @override String get storageKey => 'Campaigns'; diff --git a/lib/app/modules/Campaign/CampaignsList/bindings/campaigns_list_binding.dart b/lib/app/modules/Campaign/CampaignsList/bindings/campaigns_list_binding.dart new file mode 100644 index 00000000..c9796b4e --- /dev/null +++ b/lib/app/modules/Campaign/CampaignsList/bindings/campaigns_list_binding.dart @@ -0,0 +1,12 @@ +import 'package:get/get.dart'; + +import '../controllers/campaigns_list_controller.dart'; + +class CampaignsListBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut( + () => CampaignsListController(), + ); + } +} diff --git a/lib/app/modules/Campaign/CampaignsList/controllers/campaigns_list_controller.dart b/lib/app/modules/Campaign/CampaignsList/controllers/campaigns_list_controller.dart new file mode 100644 index 00000000..81a2158c --- /dev/null +++ b/lib/app/modules/Campaign/CampaignsList/controllers/campaigns_list_controller.dart @@ -0,0 +1,29 @@ +import 'dart:async'; + +import 'package:dungeon_paper/app/data/models/campaign.dart'; +import 'package:dungeon_paper/core/storage_handler/storage_handler.dart'; +import 'package:get/get.dart'; + +class CampaignsListController extends GetxController { + StreamSubscription? _campaignsListenerSubscription; + final _campaigns = [].obs; + + List get campaigns => _campaigns.toList(); + + final count = 0.obs; + @override + void onInit() { + super.onInit(); + _campaignsListenerSubscription = StorageHandler.instance.collectionListener('Campaigns', _campaignsListener); + } + + @override + void onClose() { + _campaignsListenerSubscription?.cancel(); + super.onClose(); + } + + void _campaignsListener(List data) { + _campaigns.value = data.map((e) => Campaign.fromJson(e)).toList(); + } +} diff --git a/lib/app/modules/Campaign/CampaignsList/views/campaigns_list_view.dart b/lib/app/modules/Campaign/CampaignsList/views/campaigns_list_view.dart new file mode 100644 index 00000000..7d3f492c --- /dev/null +++ b/lib/app/modules/Campaign/CampaignsList/views/campaigns_list_view.dart @@ -0,0 +1,39 @@ +import 'package:dungeon_paper/app/data/models/campaign.dart'; +import 'package:dungeon_paper/generated/l10n.dart'; +import 'package:flutter/material.dart'; + +import 'package:get/get.dart'; + +import '../controllers/campaigns_list_controller.dart'; + +class CampaignsListView extends GetView { + const CampaignsListView({Key? key}) : super(key: key); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(S.current.myGeneric(S.current.entityPlural(Campaign))), + centerTitle: true, + ), + body: Obx( + () => controller.campaigns.isEmpty + ? Center( + child: Text(S.current.noGeneric(S.current.entityPlural(Campaign))), + ) + : ListView.builder( + itemCount: controller.campaigns.length, + itemBuilder: (context, index) { + final campaign = controller.campaigns[index]; + return ListTile( + title: Text(campaign.name), + subtitle: Text(campaign.description), + // onTap: () => controller.openCampaign(campaign), + // ignore: avoid_returning_null_for_void + onTap: () => null, + ); + }, + ), + ), + ); + } +} diff --git a/lib/app/modules/Campaign/bindings/campaign_binding.dart b/lib/app/modules/Campaign/bindings/campaign_binding.dart new file mode 100644 index 00000000..917fa93f --- /dev/null +++ b/lib/app/modules/Campaign/bindings/campaign_binding.dart @@ -0,0 +1,12 @@ +import 'package:get/get.dart'; + +import '../controllers/campaign_controller.dart'; + +class CampaignBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut( + () => CampaignController(), + ); + } +} diff --git a/lib/app/modules/Campaign/controllers/campaign_controller.dart b/lib/app/modules/Campaign/controllers/campaign_controller.dart new file mode 100644 index 00000000..74d2e55b --- /dev/null +++ b/lib/app/modules/Campaign/controllers/campaign_controller.dart @@ -0,0 +1,23 @@ +import 'package:get/get.dart'; + +class CampaignController extends GetxController { + //TODO: Implement CampaignController + + final count = 0.obs; + @override + void onInit() { + super.onInit(); + } + + @override + void onReady() { + super.onReady(); + } + + @override + void onClose() { + super.onClose(); + } + + void increment() => count.value++; +} diff --git a/lib/app/modules/Campaign/views/campaign_view.dart b/lib/app/modules/Campaign/views/campaign_view.dart new file mode 100644 index 00000000..85c9b59e --- /dev/null +++ b/lib/app/modules/Campaign/views/campaign_view.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; + +import 'package:get/get.dart'; + +import '../controllers/campaign_controller.dart'; + +class CampaignView extends GetView { + const CampaignView({Key? key}) : super(key: key); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('CampaignView'), + centerTitle: true, + ), + body: const Center( + child: Text( + 'CampaignView is working', + style: TextStyle(fontSize: 20), + ), + ), + ); + } +} diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index 1fe64c55..6f064fc7 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -1,9 +1,3 @@ -import 'package:dungeon_paper/app/widgets/forms/character_class_form.dart'; -import 'package:dungeon_paper/app/widgets/forms/item_form.dart'; -import 'package:dungeon_paper/app/widgets/forms/move_form.dart'; -import 'package:dungeon_paper/app/widgets/forms/note_form.dart'; -import 'package:dungeon_paper/app/widgets/forms/race_form.dart'; -import 'package:dungeon_paper/app/widgets/forms/spell_form.dart'; import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; @@ -30,6 +24,10 @@ import '../modules/BioForm/bindings/bio_form_binding.dart'; import '../modules/BioForm/views/bio_form_view.dart'; import '../modules/BondsFlagsForm/bindings/bonds_flags_form_binding.dart'; import '../modules/BondsFlagsForm/views/bonds_flags_form_view.dart'; +import '../modules/Campaign/CampaignsList/bindings/campaigns_list_binding.dart'; +import '../modules/Campaign/CampaignsList/views/campaigns_list_view.dart'; +import '../modules/Campaign/bindings/campaign_binding.dart'; +import '../modules/Campaign/views/campaign_view.dart'; import '../modules/CharacterList/bindings/character_list_binding.dart'; import '../modules/CharacterList/views/character_list_view.dart'; import '../modules/ClassAlignments/bindings/class_alignments_binding.dart'; @@ -65,6 +63,12 @@ import '../modules/StartingGearForm/bindings/starting_gear_form_binding.dart'; import '../modules/StartingGearForm/views/starting_gear_form_view.dart'; import '../modules/UniversalSearch/bindings/universal_search_binding.dart'; import '../modules/UniversalSearch/views/universal_search_view.dart'; +import '../widgets/forms/character_class_form.dart'; +import '../widgets/forms/item_form.dart'; +import '../widgets/forms/move_form.dart'; +import '../widgets/forms/note_form.dart'; +import '../widgets/forms/race_form.dart'; +import '../widgets/forms/spell_form.dart'; import '../widgets/molecules/user_menu_popover.dart'; import '../widgets/views/roll_dice_view.dart'; import 'custom_transitions.dart'; @@ -343,6 +347,11 @@ class AppPages { page: () => const SendFeedbackView(), binding: SendFeedbackBinding(), ), + GetPage( + name: _Paths.campaigns, + page: () => const CampaignsListView(), + binding: CampaignsListBinding(), + ), ]; } diff --git a/lib/app/routes/app_routes.dart b/lib/app/routes/app_routes.dart index 14507873..7cca3289 100644 --- a/lib/app/routes/app_routes.dart +++ b/lib/app/routes/app_routes.dart @@ -95,22 +95,28 @@ abstract class Routes { static const createCharacter = _Paths.character + _Paths.create; /// `/character/create/roll-stats` - static const createCharacterAbilityScores = _Paths.character + _Paths.create + _Paths.abilityScores; + static const createCharacterAbilityScores = + _Paths.character + _Paths.create + _Paths.abilityScores; /// `/character/create/basic-info` - static const createCharacterBasicInfo = _Paths.character + _Paths.create + _Paths.basicInfo; + static const createCharacterBasicInfo = + _Paths.character + _Paths.create + _Paths.basicInfo; /// `/character/create/moves-and-spells` - static const createCharacterMovesSpells = _Paths.character + _Paths.create + _Paths.selectMovesSpells; + static const createCharacterMovesSpells = + _Paths.character + _Paths.create + _Paths.selectMovesSpells; - /// `/character/create/`class - static const createCharacterSelectClass = _Paths.character + _Paths.create + _Paths.characterClass; + /// `/character/create/class` + static const createCharacterSelectClass = + _Paths.character + _Paths.create + _Paths.characterClass; /// `/character/create/starting-gear` - static const createCharacterStartingGear = _Paths.character + _Paths.create + _Paths.startingGear; + static const createCharacterStartingGear = + _Paths.character + _Paths.create + _Paths.startingGear; /// `/character/class` - static const characterClass = _Paths.character + _Paths.characterClass; // TODO add page + static const characterClass = + _Paths.character + _Paths.characterClass; // TODO add page /// `/character/ability-score` static const abilityScoreForm = _Paths.character + _Paths.abilityScoreForm; @@ -138,6 +144,9 @@ abstract class Routes { /// `/feedback` static const sendFeedback = _Paths.sendFeedback; + + /// `/campaigns` + static const campaigns = _Paths.campaigns; } abstract class _Paths { @@ -235,4 +244,7 @@ abstract class _Paths { /// `/feedback` static const sendFeedback = '/feedback'; + + /// `/campaign` + static const campaigns = '/campaigns'; } diff --git a/lib/app/widgets/molecules/user_menu_popover.dart b/lib/app/widgets/molecules/user_menu_popover.dart index b7ecf3dd..b275b29e 100644 --- a/lib/app/widgets/molecules/user_menu_popover.dart +++ b/lib/app/widgets/molecules/user_menu_popover.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'dart:ui'; +import 'package:dungeon_paper/app/data/models/campaign.dart'; import 'package:dungeon_paper/app/data/models/character.dart'; import 'package:dungeon_paper/app/data/services/auth_service.dart'; import 'package:dungeon_paper/app/data/services/character_service.dart'; @@ -166,6 +167,17 @@ class UserMenuPopover extends GetView with AuthServiceMixin, U Get.toNamed(Routes.library); }, ), + if (user.isDm) + // My Campaigns + ListTile( + visualDensity: VisualDensity.compact, + title: Text(S.current.myGeneric(S.current.entityPlural(Campaign))), + leading: Icon(Campaign.genericIcon), + onTap: () { + Get.back(); + Get.toNamed(Routes.campaigns); + }, + ), // Export/Import ListTile( visualDensity: VisualDensity.compact, diff --git a/lib/routes.dart b/lib/routes.dart deleted file mode 100644 index b45b1982..00000000 --- a/lib/routes.dart +++ /dev/null @@ -1,154 +0,0 @@ -enum Routes { - // Home - home, - battle, - reference, - inventory, - notes, - -// General - about, - account, - settings, - backup, - dice, - - // Campaigns - campaignsList, - - // Custom Classes - customClassesList, - customClassCreate, - customClassEdit, - - // Characters - characterList, - characterCreate, - characterEdit, - statEdit, - - // Moves - moveAdd, - moveEdit, - - // RaceMoves - raceMoveAdd, - raceMoveEdit, - - // Spells - spellAdd, - spellEdit, - - // Inventory Items - itemAdd, - itemEdit, - - // Notes - noteAdd, - noteEdit, -} - -extension RouteData on Routes { - String get path => routePaths[this]; - String get analyticsName => routeNames[this]; -} - -final routePaths = { - // Home - Routes.home: '/', - Routes.battle: '/battle', - Routes.reference: '/reference', - Routes.inventory: '/inventory', - Routes.notes: '/notes', - - // General - Routes.about: '/about', - Routes.account: '/account', - Routes.settings: '/settings', - Routes.backup: '/settings/backup', - Routes.dice: '/dice', - - // Campaigns - Routes.campaignsList: '/campaigns', - - // Custom Classes - Routes.customClassesList: '/custom-classes', - Routes.customClassCreate: '/custom-classes/create', - Routes.customClassEdit: '/custom-classes/edit', - - // Characters - Routes.characterList: '/characters', - Routes.characterCreate: '/characters/create', - Routes.characterEdit: '/characters/edit', - Routes.statEdit: '/stat/edit', - - // Moves - Routes.moveAdd: '/moves/add', - Routes.moveEdit: '/moves/edit', - - // RaceMoves - Routes.raceMoveAdd: '/race-moves/add', - Routes.raceMoveEdit: '/race-moves/edit', - - // Spells - Routes.spellAdd: '/spells/add', - Routes.spellEdit: '/spells/edit', - - // Inventory Items - Routes.itemAdd: '/items/add', - Routes.itemEdit: '/items/edit', - - // Notes - Routes.noteAdd: '/notes/add', - Routes.noteEdit: '/notes/edit', -}; - -final routeNames = { - // Home - Routes.home: 'Home', - Routes.battle: 'Battle', - Routes.reference: 'Reference', - Routes.inventory: 'Inventory', - Routes.notes: 'Notes', - - // General - Routes.about: 'About', - Routes.account: 'Account', - Routes.settings: 'Settings', - Routes.backup: 'Backup', - Routes.dice: 'Dice', - - // Campaigns - Routes.campaignsList: 'Campaigns', - - // Custom Classes - Routes.customClassesList: 'Custom Classes', - Routes.customClassCreate: 'Create Custom Class', - Routes.customClassEdit: 'Edit Custom Class', - - // Characters - Routes.characterList: 'Characters', - Routes.characterCreate: 'Create Character', - Routes.characterEdit: 'Edit Character', - Routes.statEdit: 'Edit Stat', - - // Moves - Routes.moveAdd: 'Add Move', - Routes.moveEdit: 'Edit Moves', - - // RaceMoves - Routes.raceMoveAdd: 'Add Race move', - Routes.raceMoveEdit: 'Edit Race Moves', - - // Spells - Routes.spellAdd: 'Add Spell', - Routes.spellEdit: 'Edit Spell', - - // Inventory Items - Routes.itemAdd: 'Add Item', - Routes.itemEdit: 'Edit Item', - - // Notes - Routes.noteAdd: 'Add Note', - Routes.noteEdit: 'Edit Note', -}; diff --git a/pubspec.yaml b/pubspec.yaml index 4bae3a2c..e7bfc45b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: dungeon_paper description: A new Flutter project. -version: 2.0.0+291 +version: 2.0.0+292 # The above field defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +.