Skip to content

Commit

Permalink
Merge pull request #46 from xsoulspace/emoji-and-info
Browse files Browse the repository at this point in the history
Emoji and info
  • Loading branch information
Arenukvern authored Oct 25, 2021
2 parents 1337ecc + 347aa0c commit 294ec69
Show file tree
Hide file tree
Showing 28 changed files with 13,138 additions and 98 deletions.
12,643 changes: 12,643 additions & 0 deletions assets/emojis.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/abstract/abstract.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ part 'current_state_keys.dart';
part 'deprecated/answer.dart';
part 'deprecated/project.dart';
part 'deprecated/question.dart';
part 'emoji.dart';
part 'hive_boxes_ids.dart';
part 'idea_project/idea_project.dart';
part 'idea_project/idea_project_answer.dart';
Expand Down
12 changes: 12 additions & 0 deletions lib/abstract/abstract.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions lib/abstract/emoji.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
part of abstract;

@immutable
@JsonSerializable()
class Emoji {
const Emoji({
required final this.category,
required final this.emoji,
required final this.keywords,
});
static Emoji fromJson(final Map<String, dynamic> json) =>
_$EmojiFromJson(json);
Map<String, dynamic> toJson() => _$EmojiToJson(this);
final String category;
final String emoji;
final String keywords;
}
2 changes: 1 addition & 1 deletion lib/abstract/story_project/story_project.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
part of abstract;

/// TODO: implement StoryProject
/// TODO(arenukvern): implement StoryProject
@HiveType(typeId: HiveBoxesIds.storyProject)
class StoryProject extends BasicProject {
StoryProject({
Expand Down
1 change: 1 addition & 0 deletions lib/gen/assets.gen.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

137 changes: 137 additions & 0 deletions lib/library/widgets/emoji_grid.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
part of widgets;

class EmojiPopup extends HookWidget {
const EmojiPopup({
required final this.controller,
final Key? key,
}) : super(key: key);
final TextEditingController controller;
@override
Widget build(final BuildContext context) {
final popupVisible = useIsBool();
final screenLayout = ScreenLayout.of(context);
if (screenLayout.small && !isDesktop) return const SizedBox();
return PortalEntry(
visible: popupVisible.value,
portalAnchor:
screenLayout.large ? Alignment.bottomLeft : Alignment.bottomRight,
childAnchor: screenLayout.large ? Alignment.topRight : Alignment.topLeft,
portal: EmojiGrid(
onChanged: (final emoji) {
final emojiChar = emoji.emoji;
// Get cursor current position
final cursorPos = controller.selection.base.offset;

// Right text of cursor position
final suffixText = controller.text.substring(cursorPos);

// Add new text on cursor position
final length = emojiChar.length;

// Get the left text of cursor
final prefixText = controller.text.substring(0, cursorPos);

controller
..text = prefixText + emojiChar + suffixText

// Cursor move to end of added text
..selection = TextSelection(
baseOffset: cursorPos + length,
extentOffset: cursorPos + length,
);
},
onClose: () => popupVisible.value = false,
),
child: MouseRegion(
onHover: (final _) => popupVisible.value = true,
child: IconButton(
onPressed: () => popupVisible.value = !popupVisible.value,
icon: const Icon(Icons.emoji_emotions),
),
),
);
}
}

class EmojiGrid extends ConsumerWidget {
const EmojiGrid({
required final this.onChanged,
required final this.onClose,
final Key? key,
}) : super(key: key);
final ValueChanged<Emoji> onChanged;
final VoidCallback onClose;
@override
Widget build(final BuildContext context, final WidgetRef ref) {
final emojis = ref.read(emojisProvider);
final theme = Theme.of(context);
final borderColor = theme.brightness == Brightness.dark
? AppColors.cleanBlack
: AppColors.grey4;
return Card(
elevation: 0,
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: defaultBorderRadius,
side: BorderSide(
color: borderColor,
),
),
child: SizedBox(
height: 300,
width: 250,
child: Stack(
children: [
ColoredBox(
color: theme.canvasColor.withOpacity(0.3),
child: const SizedBox.expand(),
).frosted(
blur: theme.brightness == Brightness.dark ? 10 : 7,
frostOpacity: 0.1,
frostColor: theme.brightness == Brightness.dark
? AppColors.cleanBlack
: AppColors.white,
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: GridView.count(
restorationId: 'emojis-grid',
shrinkWrap: true,
crossAxisCount: 6,
children: emojis.values
.map(
(final e) => TextButton(
key: ValueKey(e),
onPressed: () => onChanged(e),
child: Center(
child: Text(e.emoji),
),
),
)
.toList(),
),
),
Divider(color: borderColor, height: 1),
Material(
color: Colors.transparent,
child: Row(
children: [
IconButton(
// constraints: BoxConstraints(maxHeight: 24),
icon: const Icon(Icons.close), iconSize: 14,
onPressed: onClose,
),
],
),
),
],
),
],
),
),
);
}
}
7 changes: 6 additions & 1 deletion lib/library/widgets/widgets.dart
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
library widgets;

import 'dart:developer';
import 'dart:math' as math;

import 'package:blur/blur.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lastanswer/abstract/abstract.dart';
import 'package:lastanswer/gen/assets.gen.dart';
import 'package:lastanswer/library/hooks/hooks.dart';
import 'package:lastanswer/library/theme/theme.dart';
import 'package:lastanswer/providers/providers.dart';
import 'package:lastanswer/screens/home/home.dart';
import 'package:lastanswer/utils/utils.dart';

part 'choosable_bubble.dart';
part 'circular_loader.dart';
part 'dismissible_tile.dart';
part 'editable_bubble.dart';
part 'emoji_grid.dart';
part 'focus_bubble_container.dart';
part 'hero_id.dart';
part 'icon_add_button.dart';
Expand Down
6 changes: 6 additions & 0 deletions lib/providers/emoji_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
part of providers;

final emojisProvider =
StateNotifierProvider<MapState<Emoji>, Map<String, Emoji>>(
(final _) => MapState<Emoji>(),
);
2 changes: 2 additions & 0 deletions lib/providers/projects.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class MapState<TValue> extends StateNotifier<Map<String, TValue>> {
...state,
...map,
};
void putEntries(final Iterable<MapEntry<String, TValue>> newEntries) =>
state = {...state}..addEntries(newEntries);

void remove({required final String key}) => state = {
...state,
Expand Down
1 change: 1 addition & 0 deletions lib/providers/providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ library providers;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lastanswer/abstract/abstract.dart';

part 'emoji_provider.dart';
part 'projects.dart';
13 changes: 8 additions & 5 deletions lib/screens/app/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:lastanswer/abstract/abstract.dart';
Expand All @@ -28,11 +29,13 @@ class AppProvider extends StatelessWidget {

@override
Widget build(final BuildContext context) {
return ProviderScope(
child: SettingsStateScope(
notifier: _settings,
child: const AppStoreInitializer(
child: AppScaffold(),
return Portal(
child: ProviderScope(
child: SettingsStateScope(
notifier: _settings,
child: const AppStoreInitializer(
child: AppScaffold(),
),
),
),
);
Expand Down
46 changes: 42 additions & 4 deletions lib/screens/app/app_store_initializer.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
part of app_provider;

enum AppStateLoadingStatuses {
settings,
emoji,
ideas,
questionsForAnswers,
answersForIdeas,
notes,
migratingOldData,
}

Future<Box<T>> openAnyway<T>(final String boxName) async {
try {
await Hive.openBox<T>(boxName);
Expand Down Expand Up @@ -33,11 +43,24 @@ class AppStoreInitializer extends ConsumerWidget {
settings
..appInitialStateLoaded = true
..appInitialStateIsLoading = true;
await SettingsStateScope.of(context).load();

final settingsState = SettingsStateScope.of(context);
await settingsState.load();

settingsState.loadingStatus = AppStateLoadingStatuses.emoji;
final emojis = await EmojiUtil.getList(context);

ref
.read(emojisProvider.notifier)
.putEntries(emojis.map((final e) => MapEntry(e.keywords, e)));

settings.loadingStatus = AppStateLoadingStatuses.ideas;

await openAnyway<IdeaProjectAnswer>(HiveBoxesIds.ideaProjectAnswerKey);

final ideas =
await openAnyway<IdeaProject>(HiveBoxesIds.ideaProjectKey);
settings.loadingStatus = AppStateLoadingStatuses.questionsForAnswers;

final questions = await openAnyway<IdeaProjectQuestion>(
HiveBoxesIds.ideaProjectQuestionKey,
Expand All @@ -49,18 +72,21 @@ class AppStoreInitializer extends ConsumerWidget {
),
);
}
settings.loadingStatus = AppStateLoadingStatuses.answersForIdeas;

ref.read(ideaProjectQuestionsProvider.notifier).putAll(
Map.fromEntries(
questions.values.map((final e) => MapEntry(e.id, e)),
),
);
settings.loadingStatus = AppStateLoadingStatuses.answersForIdeas;

ref.read(ideaProjectsProvider.notifier).putAll(
Map.fromEntries(
ideas.values.map((final e) => MapEntry(e.id, e)),
),
);
settings.loadingStatus = AppStateLoadingStatuses.notes;

final notes = await openAnyway<NoteProject>(
HiveBoxesIds.noteProjectKey,
Expand All @@ -75,6 +101,8 @@ class AppStoreInitializer extends ConsumerWidget {
HiveBoxesIds.storyProjectKey,
);

settings.loadingStatus = AppStateLoadingStatuses.migratingOldData;

/// ***************** MIGRATION START *******************
try {
// TODO(arenukvern): remove old stores after all devices migration
Expand Down Expand Up @@ -113,9 +141,19 @@ class AppStoreInitializer extends ConsumerWidget {
color: brightness == Brightness.dark
? AppColors.black
: AppColors.white,
child: const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(AppColors.primary2),
child: Center(
child: Directionality(
textDirection: TextDirection.ltr,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(AppColors.primary2),
),
const SizedBox(height: 5),
Text(settings.loadingStatus.toString()),
],
),
),
),
);
Expand Down
Loading

0 comments on commit 294ec69

Please sign in to comment.