Second step of remaking the example

pull/1530/head
Ellet 1 year ago
parent 4ff25f24ee
commit 5d3e600645
No known key found for this signature in database
GPG Key ID: C488CC70BBCEF0D1
  1. 4
      example/analysis_options.yaml
  2. 0
      example/lib/logic/empty.dart
  3. 78
      example/lib/main.dart
  4. 51
      example/lib/presentation/home/widgets/example_item.dart
  5. 120
      example/lib/presentation/home/widgets/home_screen.dart
  6. 102
      example/lib/presentation/quill/quill_images_screen.dart
  7. 92
      example/lib/presentation/quill/quill_screen.dart
  8. 24
      example/lib/presentation/settings/cubit/settings_cubit.dart
  9. 175
      example/lib/presentation/settings/cubit/settings_cubit.freezed.dart
  10. 36
      example/lib/presentation/settings/cubit/settings_cubit.g.dart
  11. 21
      example/lib/presentation/settings/cubit/settings_state.dart
  12. 105
      example/lib/presentation/settings/widgets/settings_screen.dart
  13. 63
      example/lib/presentation/shared/widgets/dialog_action.dart
  14. 24
      example/lib/presentation/shared/widgets/home_screen_button.dart
  15. 2
      example/macos/Flutter/GeneratedPluginRegistrant.swift
  16. 14
      example/pubspec.yaml
  17. 3
      example/windows/flutter/generated_plugin_registrant.cc
  18. 1
      example/windows/flutter/generated_plugins.cmake
  19. 15
      flutter_quill_extensions/lib/presentation/embeds/widgets/image_resizer.dart

@ -1,5 +1,9 @@
include: package:flutter_lints/flutter.yaml
analyzer:
errors:
invalid_annotation_target: ignore
linter:
rules:
always_declare_return_types: true

@ -1,5 +1,6 @@
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart'
show
GlobalCupertinoLocalizations,
@ -12,6 +13,9 @@ import 'package:path_provider/path_provider.dart'
show getApplicationDocumentsDirectory;
import 'presentation/home/widgets/home_screen.dart';
import 'presentation/quill/quill_images_screen.dart';
import 'presentation/settings/cubit/settings_cubit.dart';
import 'presentation/settings/widgets/settings_screen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
@ -28,20 +32,68 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Quill Demo',
theme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
themeMode: ThemeMode.system,
debugShowCheckedModeBanner: false,
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
FlutterQuillLocalizations.delegate,
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => SettingsCubit(),
),
],
supportedLocales: FlutterQuillLocalizations.supportedLocales,
home: const HomePage(),
child: BlocBuilder<SettingsCubit, SettingsState>(
builder: (context, state) {
return MaterialApp(
title: 'Flutter Quill Demo',
theme: ThemeData.light(useMaterial3: true),
darkTheme: ThemeData.dark(useMaterial3: true),
themeMode: state.themeMode,
debugShowCheckedModeBanner: false,
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
FlutterQuillLocalizations.delegate,
],
supportedLocales: FlutterQuillLocalizations.supportedLocales,
routes: {
SettingsScreen.routeName: (context) => const SettingsScreen(),
QuillImagesScreen.routeName: (context) =>
const QuillImagesScreen(),
},
home: Builder(
builder: (context) {
final screen = switch (state.defaultScreen) {
DefaultScreen.home => const HomePage(),
DefaultScreen.settings => const SettingsScreen(),
DefaultScreen.images => const QuillImagesScreen(),
DefaultScreen.videos => null,
DefaultScreen.text => null,
};
return AnimatedSwitcher(
duration: const Duration(milliseconds: 330),
transitionBuilder: (child, animation) {
// This animation is from flutter.dev example
const begin = Offset(0, 1);
const end = Offset.zero;
const curve = Curves.ease;
final tween = Tween(
begin: begin,
end: end,
).chain(
CurveTween(curve: curve),
);
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
child: screen,
);
},
),
);
},
),
);
}
}

@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
class HomeScreenExampleItem extends StatelessWidget {
const HomeScreenExampleItem({
required this.title,
required this.icon,
required this.text,
required this.onPressed,
super.key,
});
final String title;
final Widget icon;
final String text;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
return Column(
children: [
SizedBox(
height: 200,
width: double.infinity,
child: GestureDetector(
onTap: onPressed,
child: Card(
child: Column(
children: [
const SizedBox(height: 2),
Text(
title,
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
icon,
const SizedBox(height: 8),
Padding(
padding: const EdgeInsets.all(8),
child: Text(
text,
style: Theme.of(context).textTheme.bodyMedium,
),
),
],
),
),
),
),
],
);
}
}

@ -1,39 +1,111 @@
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
import '../../quill/quill_images_screen.dart';
import '../../quill/quill_screen.dart';
import '../../settings/widgets/settings_screen.dart';
import 'example_item.dart';
@override
State<HomePage> createState() => _HomePageState();
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
class _HomePageState extends State<HomePage> {
final _controller = QuillController.basic();
@override
Widget build(BuildContext context) {
return QuillProvider(
configurations: QuillConfigurations(
controller: _controller,
sharedConfigurations: QuillSharedConfigurations(
animationConfigurations: QuillAnimationConfigurations.disableAll(),
),
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Quill Demo'),
),
child: Scaffold(
appBar: AppBar(
title: const Text('Flutter Quill Demo'),
drawer: Drawer(
child: ListView(
children: [
const DrawerHeader(
child: Text(
'Flutter Quill Demo',
),
),
ListTile(
title: const Text('Settings'),
leading: const Icon(Icons.settings),
onTap: () {
Navigator.of(context)
..pop()
..pushNamed(SettingsScreen.routeName);
},
),
],
),
body: Column(
),
body: SafeArea(
child: Column(
children: [
const QuillToolbar(),
SizedBox(
width: double.infinity,
child: Text(
'Welcome to Flutter Quill Demo!',
style: Theme.of(context).textTheme.titleLarge,
textAlign: TextAlign.center,
),
),
Expanded(
child: QuillEditor.basic(
configurations: const QuillEditorConfigurations(
scrollable: true,
padding: EdgeInsets.all(16),
),
child: ListView(
padding: const EdgeInsets.all(16),
children: [
HomeScreenExampleItem(
title: 'Images',
icon: const Icon(
Icons.image,
size: 50,
),
text: 'If you want to see how the editor work with images, '
'see any samples or you are working on it',
onPressed: () {
Navigator.of(context)
.pushNamed(QuillImagesScreen.routeName);
},
),
const SizedBox(height: 4),
HomeScreenExampleItem(
title: 'Videos',
icon: const Icon(
Icons.video_chat,
size: 50,
),
text: 'If you want to see how the editor work with videos, '
'see any samples or you are working on it',
onPressed: () {},
),
HomeScreenExampleItem(
title: 'Text',
icon: const Icon(
Icons.edit_document,
size: 50,
),
text: 'If you want to see how the editor work with text, '
'see any samples or you are working on it',
onPressed: () {},
),
HomeScreenExampleItem(
title: 'Empty',
icon: const Icon(
Icons.insert_drive_file,
size: 50,
),
text: 'Want start clean? be my guest',
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return QuillScreen(
document: Document(),
);
},
),
);
},
),
],
),
)
),
],
),
),

File diff suppressed because one or more lines are too long

@ -0,0 +1,92 @@
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
import 'package:share_plus/share_plus.dart' show Share;
class QuillScreen extends StatefulWidget {
const QuillScreen({
required this.document,
super.key,
});
final Document document;
@override
State<QuillScreen> createState() => _QuillScreenState();
}
class _QuillScreenState extends State<QuillScreen> {
final _controller = QuillController.basic();
final _isReadOnly = false;
@override
void initState() {
super.initState();
_controller.document = widget.document;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Quill'),
actions: [
IconButton(
onPressed: () {
final plainText = _controller.document.toPlainText(
FlutterQuillEmbeds.defaultEditorBuilders(),
);
if (plainText.trim().isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
"We can't share empty document, please enter some text first",
),
),
);
return;
}
Share.share(plainText);
},
icon: const Icon(Icons.share),
),
],
),
body: QuillProvider(
configurations: QuillConfigurations(
controller: _controller,
sharedConfigurations: QuillSharedConfigurations(
animationConfigurations: QuillAnimationConfigurations.disableAll(),
extraConfigurations: const {
QuillSharedExtensionsConfigurations.key:
QuillSharedExtensionsConfigurations(
assetsPrefix: 'assets',
),
},
),
),
child: Column(
children: [
QuillToolbar(
configurations: QuillToolbarConfigurations(
embedButtons: FlutterQuillEmbeds.toolbarButtons(),
),
),
Expanded(
child: QuillEditor.basic(
configurations: QuillEditorConfigurations(
scrollable: true,
readOnly: _isReadOnly,
placeholder: 'Start writting your notes...',
padding: const EdgeInsets.all(16),
embedBuilders: FlutterQuillEmbeds.defaultEditorBuilders(),
),
),
),
],
),
),
);
}
}

@ -1,8 +1,26 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart' show ThemeMode;
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart' show HydratedMixin;
part 'settings_state.dart';
part 'settings_cubit.freezed.dart';
part 'settings_cubit.g.dart';
class SettingsCubit extends Cubit<SettingsState> {
SettingsCubit() : super(SettingsInitial());
class SettingsCubit extends Cubit<SettingsState> with HydratedMixin {
SettingsCubit() : super(const SettingsState());
void updateSettings(SettingsState newSettingsState) {
emit(newSettingsState);
}
@override
SettingsState? fromJson(Map<String, dynamic> json) {
return SettingsState.fromJson(json);
}
@override
Map<String, dynamic>? toJson(SettingsState state) {
return state.toJson();
}
}

@ -0,0 +1,175 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'settings_cubit.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
SettingsState _$SettingsStateFromJson(Map<String, dynamic> json) {
return _SettingsState.fromJson(json);
}
/// @nodoc
mixin _$SettingsState {
ThemeMode get themeMode => throw _privateConstructorUsedError;
DefaultScreen get defaultScreen => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$SettingsStateCopyWith<SettingsState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $SettingsStateCopyWith<$Res> {
factory $SettingsStateCopyWith(
SettingsState value, $Res Function(SettingsState) then) =
_$SettingsStateCopyWithImpl<$Res, SettingsState>;
@useResult
$Res call({ThemeMode themeMode, DefaultScreen defaultScreen});
}
/// @nodoc
class _$SettingsStateCopyWithImpl<$Res, $Val extends SettingsState>
implements $SettingsStateCopyWith<$Res> {
_$SettingsStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? themeMode = null,
Object? defaultScreen = null,
}) {
return _then(_value.copyWith(
themeMode: null == themeMode
? _value.themeMode
: themeMode // ignore: cast_nullable_to_non_nullable
as ThemeMode,
defaultScreen: null == defaultScreen
? _value.defaultScreen
: defaultScreen // ignore: cast_nullable_to_non_nullable
as DefaultScreen,
) as $Val);
}
}
/// @nodoc
abstract class _$$SettingsStateImplCopyWith<$Res>
implements $SettingsStateCopyWith<$Res> {
factory _$$SettingsStateImplCopyWith(
_$SettingsStateImpl value, $Res Function(_$SettingsStateImpl) then) =
__$$SettingsStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({ThemeMode themeMode, DefaultScreen defaultScreen});
}
/// @nodoc
class __$$SettingsStateImplCopyWithImpl<$Res>
extends _$SettingsStateCopyWithImpl<$Res, _$SettingsStateImpl>
implements _$$SettingsStateImplCopyWith<$Res> {
__$$SettingsStateImplCopyWithImpl(
_$SettingsStateImpl _value, $Res Function(_$SettingsStateImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? themeMode = null,
Object? defaultScreen = null,
}) {
return _then(_$SettingsStateImpl(
themeMode: null == themeMode
? _value.themeMode
: themeMode // ignore: cast_nullable_to_non_nullable
as ThemeMode,
defaultScreen: null == defaultScreen
? _value.defaultScreen
: defaultScreen // ignore: cast_nullable_to_non_nullable
as DefaultScreen,
));
}
}
/// @nodoc
@JsonSerializable()
class _$SettingsStateImpl implements _SettingsState {
const _$SettingsStateImpl(
{this.themeMode = ThemeMode.system,
this.defaultScreen = DefaultScreen.home});
factory _$SettingsStateImpl.fromJson(Map<String, dynamic> json) =>
_$$SettingsStateImplFromJson(json);
@override
@JsonKey()
final ThemeMode themeMode;
@override
@JsonKey()
final DefaultScreen defaultScreen;
@override
String toString() {
return 'SettingsState(themeMode: $themeMode, defaultScreen: $defaultScreen)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SettingsStateImpl &&
(identical(other.themeMode, themeMode) ||
other.themeMode == themeMode) &&
(identical(other.defaultScreen, defaultScreen) ||
other.defaultScreen == defaultScreen));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(runtimeType, themeMode, defaultScreen);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$SettingsStateImplCopyWith<_$SettingsStateImpl> get copyWith =>
__$$SettingsStateImplCopyWithImpl<_$SettingsStateImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$SettingsStateImplToJson(
this,
);
}
}
abstract class _SettingsState implements SettingsState {
const factory _SettingsState(
{final ThemeMode themeMode,
final DefaultScreen defaultScreen}) = _$SettingsStateImpl;
factory _SettingsState.fromJson(Map<String, dynamic> json) =
_$SettingsStateImpl.fromJson;
@override
ThemeMode get themeMode;
@override
DefaultScreen get defaultScreen;
@override
@JsonKey(ignore: true)
_$$SettingsStateImplCopyWith<_$SettingsStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}

@ -0,0 +1,36 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'settings_cubit.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$SettingsStateImpl _$$SettingsStateImplFromJson(Map<String, dynamic> json) =>
_$SettingsStateImpl(
themeMode: $enumDecodeNullable(_$ThemeModeEnumMap, json['themeMode']) ??
ThemeMode.system,
defaultScreen:
$enumDecodeNullable(_$DefaultScreenEnumMap, json['defaultScreen']) ??
DefaultScreen.home,
);
Map<String, dynamic> _$$SettingsStateImplToJson(_$SettingsStateImpl instance) =>
<String, dynamic>{
'themeMode': _$ThemeModeEnumMap[instance.themeMode]!,
'defaultScreen': _$DefaultScreenEnumMap[instance.defaultScreen]!,
};
const _$ThemeModeEnumMap = {
ThemeMode.system: 'system',
ThemeMode.light: 'light',
ThemeMode.dark: 'dark',
};
const _$DefaultScreenEnumMap = {
DefaultScreen.home: 'home',
DefaultScreen.settings: 'settings',
DefaultScreen.images: 'images',
DefaultScreen.videos: 'videos',
DefaultScreen.text: 'text',
};

@ -1,10 +1,19 @@
part of 'settings_cubit.dart';
sealed class SettingsState extends Equatable {
const SettingsState();
@override
List<Object> get props => [];
enum DefaultScreen {
home,
settings,
images,
videos,
text,
}
final class SettingsInitial extends SettingsState {}
@freezed
class SettingsState with _$SettingsState {
const factory SettingsState({
@Default(ThemeMode.system) ThemeMode themeMode,
@Default(DefaultScreen.home) DefaultScreen defaultScreen,
}) = _SettingsState;
factory SettingsState.fromJson(Map<String, Object?> json) =>
_$SettingsStateFromJson(json);
}

@ -0,0 +1,105 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_quill/translations.dart';
import '../../shared/widgets/dialog_action.dart';
import '../../shared/widgets/home_screen_button.dart';
import '../cubit/settings_cubit.dart';
class SettingsScreen extends StatelessWidget {
const SettingsScreen({super.key});
static const routeName = '/settings';
@override
Widget build(BuildContext context) {
final materialTheme = Theme.of(context);
final isDark = materialTheme.brightness == Brightness.dark;
return Scaffold(
appBar: AppBar(
title: const Text('Settings'),
actions: const [
HomeScreenButton(),
],
),
body: BlocBuilder<SettingsCubit, SettingsState>(
builder: (context, state) {
return ListView(
children: [
CheckboxListTile.adaptive(
value: isDark,
onChanged: (value) {
final isNewValueDark = value ?? false;
context.read<SettingsCubit>().updateSettings(
state.copyWith(
themeMode:
isNewValueDark ? ThemeMode.dark : ThemeMode.light,
),
);
},
title: const Text('Dark Theme'),
subtitle: const Text(
'By default we will use your system theme, but you can set if you want dark or light theme',
),
secondary: Icon(isDark ? Icons.nightlight : Icons.sunny),
),
ListTile(
title: const Text('Default screen'),
subtitle: const Text(
'Which screen should be used when the flutter app starts?',
),
leading: const Icon(Icons.home),
onTap: () async {
final settingsBloc = context.read<SettingsCubit>();
final newDefaultScreen =
await showAdaptiveDialog<DefaultScreen>(
context: context,
builder: (context) {
return AlertDialog.adaptive(
title: const Text('Select default screen'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
...DefaultScreen.values.map(
(e) => ListTile(
onTap: () {
Navigator.of(context).pop(e);
},
title: Text(e.name),
leading: CircleAvatar(
child: Text((e.index + 1).toString()),
),
),
),
],
),
actions: [
AppDialogAction(
onPressed: () => Navigator.of(context).pop(null),
options: const DialogActionOptions(
cupertinoDialogActionOptions:
CupertinoDialogActionOptions(
isDefaultAction: true,
),
),
child: const Text('Cancel'),
),
],
);
},
);
if (newDefaultScreen != null) {
settingsBloc.updateSettings(
settingsBloc.state
.copyWith(defaultScreen: newDefaultScreen),
);
}
},
),
],
);
},
),
);
}
}

@ -0,0 +1,63 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_quill/extensions.dart';
@immutable
final class CupertinoDialogActionOptions {
const CupertinoDialogActionOptions({
this.isDefaultAction = false,
});
final bool isDefaultAction;
}
@immutable
final class MaterialDialogActionOptions {
const MaterialDialogActionOptions({
this.textStyle,
});
final ButtonStyle? textStyle;
}
@immutable
class DialogActionOptions {
const DialogActionOptions({
this.cupertinoDialogActionOptions,
this.materialDialogActionOptions,
});
final CupertinoDialogActionOptions? cupertinoDialogActionOptions;
final MaterialDialogActionOptions? materialDialogActionOptions;
}
class AppDialogAction extends StatelessWidget {
const AppDialogAction({
required this.child,
required this.onPressed,
this.options,
super.key,
});
final VoidCallback? onPressed;
final Widget child;
final DialogActionOptions? options;
@override
Widget build(BuildContext context) {
if (isAppleOS(supportWeb: true)) {
return CupertinoDialogAction(
onPressed: onPressed,
isDefaultAction:
options?.cupertinoDialogActionOptions?.isDefaultAction ?? false,
child: child,
);
}
return TextButton(
onPressed: onPressed,
style: options?.materialDialogActionOptions?.textStyle,
child: child,
);
}
}

@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../settings/cubit/settings_cubit.dart';
class HomeScreenButton extends StatelessWidget {
const HomeScreenButton({super.key});
@override
Widget build(BuildContext context) {
return IconButton(
onPressed: () {
final settingsCubit = context.read<SettingsCubit>();
settingsCubit.updateSettings(
settingsCubit.state.copyWith(
defaultScreen: DefaultScreen.home,
),
);
},
icon: const Icon(Icons.home),
tooltip: 'Set the default to home screen',
);
}
}

@ -11,6 +11,7 @@ import file_selector_macos
import gal
import pasteboard
import path_provider_foundation
import share_plus
import url_launcher_macos
import video_player_avfoundation
@ -21,6 +22,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin"))
PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
}

@ -20,12 +20,19 @@ dependencies:
# Normal Packages
path: ^1.8.3
equatable: ^2.0.5
# Bloc libraries
bloc: ^8.1.2
flutter_bloc: ^8.1.3
hydrated_bloc: ^9.1.2
# Freezed
freezed_annotation: ^2.4.1
# Json
json_annotation: ^4.8.1
# Plugins
image_cropper: ^5.0.0
path_provider: ^2.1.1
@ -33,6 +40,8 @@ dependencies:
desktop_drop: ^0.4.4
# For picking quill document files
file_picker: ^6.1.1
# For sharing text
share_plus: ^7.2.1
dependency_overrides:
flutter_quill:
@ -50,6 +59,11 @@ dev_dependencies:
flutter_lints: ^3.0.1
build_runner: ^2.4.6
flutter_gen_runner: ^5.3.2
# Freezed
freezed: ^2.4.5
# Json
json_serializable: ^6.7.1
flutter:
uses-material-design: true
assets:

@ -10,6 +10,7 @@
#include <file_selector_windows/file_selector_windows.h>
#include <gal/gal_plugin_c_api.h>
#include <pasteboard/pasteboard_plugin.h>
#include <share_plus/share_plus_windows_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
@ -21,6 +22,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("GalPluginCApi"));
PasteboardPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PasteboardPlugin"));
SharePlusWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}

@ -7,6 +7,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows
gal
pasteboard
share_plus
url_launcher_windows
)

@ -82,19 +82,18 @@ class ImageResizerState extends State<ImageResizer> {
}
Widget _slider({
required double value,
required bool isHeight,
required bool isWidth,
required ValueChanged<double> onChanged,
}) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Card(
child: Slider(
value: value,
max: widget.maxWidth,
value: isWidth ? _width : _height,
max: isWidth ? widget.maxWidth : widget.maxHeight,
divisions: 1000,
// Might need to be changed
label: isHeight ? context.loc.height : context.loc.width,
label: isWidth ? context.loc.width : context.loc.height,
onChanged: (val) {
setState(() {
onChanged(val);
@ -108,8 +107,7 @@ class ImageResizerState extends State<ImageResizer> {
Widget _heightSlider() {
return _slider(
value: _height,
isHeight: true,
isWidth: false,
onChanged: (value) {
_height = value;
},
@ -118,8 +116,7 @@ class ImageResizerState extends State<ImageResizer> {
Widget _widthSlider() {
return _slider(
value: _width,
isHeight: false,
isWidth: true,
onChanged: (value) {
_width = value;
},

Loading…
Cancel
Save