mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-09-11 19:17:43 +03:00
fix: page style issues (#5317)
* fix: 7 emojis per line * fix: remove shadow of the icons using presets cover * fix: expand appbar buttons size * fix: save new title name when it changed * feat: add cover image preview * fix: dismiss unsplash and presets panel auto * feat: add selected color for cover image and layout section * fix: selected icon size too small * fix: dismiss page style panel before pushing to emoji and font selector * chore: update back button icon * chore: bump version 0.5.7
This commit is contained in:
parent
cdcb393efd
commit
4cfd83cbc4
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,4 +1,22 @@
|
||||
# Release Notes
|
||||
## Version 0.5.7 - 05/10/2024
|
||||
### Bug Fixes
|
||||
- Resolved page opening issue on Android.
|
||||
- Fixed text input inconsistency on Kanban board cards.
|
||||
|
||||
## Version 0.5.6 - 05/07/2024
|
||||
### New Features
|
||||
- Team collaboration is live! Add members to your workspace to edit and collaborate on pages together.
|
||||
- Collaborate in real time on the same page with other members. Edits made by others will appear instantly.
|
||||
- Create multiple workspaces for different kinds of content.
|
||||
- Customize your entire page on mobile through the Page Style menu with options for layout, font, font size, emoji, and cover image.
|
||||
- Open a row record as a full page.
|
||||
### Bug Fixes
|
||||
- Resolved issue with setting background color for the Simple Table block.
|
||||
- Adjusted toolbar for various screen sizes.
|
||||
- Added a request for photo permission before uploading images on mobile.
|
||||
- Exported creation and last modification timestamps to CSV.
|
||||
|
||||
## Version 0.5.5 - 04/24/2024
|
||||
### New Features
|
||||
- Improved the display of code blocks with line numbers
|
||||
|
@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
APPFLOWY_VERSION = "0.5.6"
|
||||
APPFLOWY_VERSION = "0.5.7"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||
|
@ -1,8 +1,10 @@
|
||||
import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart';
|
||||
import 'package:appflowy/user/application/user_service.dart';
|
||||
import 'package:appflowy/workspace/application/view/prelude.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
@ -21,6 +23,9 @@ class MobileViewPageBloc
|
||||
initial: () async {
|
||||
_registerListeners();
|
||||
|
||||
final userProfilePB =
|
||||
await UserBackendService.getCurrentUserProfile()
|
||||
.fold((s) => s, (f) => null);
|
||||
final result = await ViewBackendService.getView(viewId);
|
||||
final isImmersiveMode =
|
||||
_isImmersiveMode(result.fold((s) => s, (f) => null));
|
||||
@ -29,6 +34,7 @@ class MobileViewPageBloc
|
||||
isLoading: false,
|
||||
result: result,
|
||||
isImmersiveMode: isImmersiveMode,
|
||||
userProfilePB: userProfilePB,
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -71,7 +77,7 @@ class MobileViewPageBloc
|
||||
final cover = view.cover;
|
||||
if (cover == null || cover.type == PageStyleCoverImageType.none) {
|
||||
return false;
|
||||
} else if (view.layout == ViewLayoutPB.Document) {
|
||||
} else if (view.layout == ViewLayoutPB.Document && !cover.isPresets) {
|
||||
// only support immersive mode for document layout
|
||||
return true;
|
||||
}
|
||||
@ -93,6 +99,7 @@ class MobileViewPageState with _$MobileViewPageState {
|
||||
@Default(true) bool isLoading,
|
||||
@Default(null) FlowyResult<ViewPB, FlowyError>? result,
|
||||
@Default(false) bool isImmersiveMode,
|
||||
@Default(null) UserProfilePB? userProfilePB,
|
||||
}) = _MobileViewPageState;
|
||||
|
||||
factory MobileViewPageState.initial() => const MobileViewPageState();
|
||||
|
@ -37,6 +37,7 @@ class FlowyAppBar extends AppBar {
|
||||
Widget? title,
|
||||
String? titleText,
|
||||
FlowyAppBarLeadingType leadingType = FlowyAppBarLeadingType.back,
|
||||
double? leadingWidth,
|
||||
Widget? leading,
|
||||
super.centerTitle,
|
||||
VoidCallback? onTapLeading,
|
||||
@ -52,7 +53,7 @@ class FlowyAppBar extends AppBar {
|
||||
titleSpacing: 0,
|
||||
elevation: 0,
|
||||
leading: leading ?? leadingType.getWidget(onTapLeading),
|
||||
leadingWidth: leadingType.width,
|
||||
leadingWidth: leadingWidth ?? leadingType.width,
|
||||
toolbarHeight: 44.0,
|
||||
bottom: showDivider
|
||||
? const PreferredSize(
|
||||
|
@ -43,8 +43,9 @@ class MobileViewPageImmersiveAppBar extends StatelessWidget
|
||||
AppBarTheme.of(context).backgroundColor?.withOpacity(opacity),
|
||||
showDivider: false,
|
||||
title: Opacity(opacity: opacity >= 0.99 ? 1.0 : 0, child: title),
|
||||
leadingWidth: 44,
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 2.0, vertical: 4.0),
|
||||
padding: const EdgeInsets.only(top: 4.0, bottom: 4.0, left: 12.0),
|
||||
child: _buildAppBarBackButton(context),
|
||||
),
|
||||
actions: actions,
|
||||
@ -59,7 +60,7 @@ class MobileViewPageImmersiveAppBar extends StatelessWidget
|
||||
child: _ImmersiveAppBarButton(
|
||||
icon: FlowySvgs.m_app_bar_back_s,
|
||||
dimension: 30.0,
|
||||
iconPadding: 6.0,
|
||||
iconPadding: 3.0,
|
||||
isImmersiveMode:
|
||||
context.read<MobileViewPageBloc>().state.isImmersiveMode,
|
||||
appBarOpacity: appBarOpacity,
|
||||
@ -104,7 +105,7 @@ class MobileViewPageMoreButton extends StatelessWidget {
|
||||
child: _ImmersiveAppBarButton(
|
||||
icon: FlowySvgs.m_app_bar_more_s,
|
||||
dimension: 30.0,
|
||||
iconPadding: 5.0,
|
||||
iconPadding: 3.0,
|
||||
isImmersiveMode: isImmersiveMode,
|
||||
appBarOpacity: appBarOpacity,
|
||||
),
|
||||
@ -144,8 +145,11 @@ class MobileViewPageLayoutButton extends StatelessWidget {
|
||||
showHeader: true,
|
||||
title: LocaleKeys.pageStyle_title.tr(),
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
builder: (_) => BlocProvider.value(
|
||||
value: context.read<DocumentPageStyleBloc>(),
|
||||
builder: (_) => MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider.value(value: context.read<DocumentPageStyleBloc>()),
|
||||
BlocProvider.value(value: context.read<MobileViewPageBloc>()),
|
||||
],
|
||||
child: PageStyleBottomSheet(
|
||||
view: context.read<ViewBloc>().state.view,
|
||||
),
|
||||
@ -155,7 +159,7 @@ class MobileViewPageLayoutButton extends StatelessWidget {
|
||||
child: _ImmersiveAppBarButton(
|
||||
icon: FlowySvgs.m_layout_s,
|
||||
dimension: 30.0,
|
||||
iconPadding: 5.0,
|
||||
iconPadding: 3.0,
|
||||
isImmersiveMode: isImmersiveMode,
|
||||
appBarOpacity: appBarOpacity,
|
||||
),
|
||||
|
@ -149,14 +149,11 @@ class _DocumentImmersiveCoverState extends State<DocumentImmersiveCover> {
|
||||
fontSize: 28.0,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontFamily: fontFamily,
|
||||
color: state.cover.type == PageStyleCoverImageType.none
|
||||
? null
|
||||
: Colors.white,
|
||||
color:
|
||||
state.cover.isNone || state.cover.isPresets ? null : Colors.white,
|
||||
),
|
||||
onSubmitted: (value) {
|
||||
scrollController.position.jumpTo(0);
|
||||
context.read<ViewBloc>().add(ViewEvent.rename(value));
|
||||
},
|
||||
onChanged: _rename,
|
||||
onSubmitted: _rename,
|
||||
);
|
||||
}
|
||||
|
||||
@ -250,4 +247,9 @@ class _DocumentImmersiveCoverState extends State<DocumentImmersiveCover> {
|
||||
focusNode.unfocus(disposition: UnfocusDisposition.previouslyFocusedChild);
|
||||
}
|
||||
}
|
||||
|
||||
void _rename(String name) {
|
||||
scrollController.position.jumpTo(0);
|
||||
context.read<ViewBloc>().add(ViewEvent.rename(name));
|
||||
}
|
||||
}
|
||||
|
@ -131,12 +131,16 @@ class _UnsplashImages extends StatelessWidget {
|
||||
};
|
||||
final mainAxisSpacing = switch (type) {
|
||||
UnsplashImageType.halfScreen => 16.0,
|
||||
UnsplashImageType.fullScreen => 8.0,
|
||||
UnsplashImageType.fullScreen => 16.0,
|
||||
};
|
||||
final crossAxisSpacing = switch (type) {
|
||||
UnsplashImageType.halfScreen => 10.0,
|
||||
UnsplashImageType.fullScreen => 16.0,
|
||||
};
|
||||
return GridView.count(
|
||||
crossAxisCount: crossAxisCount,
|
||||
mainAxisSpacing: mainAxisSpacing,
|
||||
crossAxisSpacing: 10.0,
|
||||
crossAxisSpacing: crossAxisSpacing,
|
||||
childAspectRatio: 4 / 3,
|
||||
children: photos
|
||||
.map(
|
||||
@ -197,28 +201,31 @@ class _UnsplashImage extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildFullScreenImage(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return Image.network(
|
||||
photo.urls.thumb.toString(),
|
||||
fit: BoxFit.cover,
|
||||
width: constraints.maxWidth,
|
||||
height: constraints.maxHeight,
|
||||
);
|
||||
},
|
||||
),
|
||||
Positioned(
|
||||
bottom: 6,
|
||||
left: 6,
|
||||
child: FlowyText.medium(
|
||||
photo.name,
|
||||
fontSize: 10.0,
|
||||
color: Colors.white,
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
child: Stack(
|
||||
children: [
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return Image.network(
|
||||
photo.urls.thumb.toString(),
|
||||
fit: BoxFit.cover,
|
||||
width: constraints.maxWidth,
|
||||
height: constraints.maxHeight,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
Positioned(
|
||||
bottom: 9,
|
||||
left: 10,
|
||||
child: FlowyText.medium(
|
||||
photo.name,
|
||||
fontSize: 13.0,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,21 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/mobile/application/base/mobile_view_page_bloc.dart';
|
||||
import 'package:appflowy/mobile/application/page_style/document_page_style_bloc.dart';
|
||||
import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/image_util.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/image/unsplash_image_widget.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/_page_cover_bottom_sheet.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/page_style/_page_style_util.dart';
|
||||
import 'package:appflowy/shared/appflowy_network_image.dart';
|
||||
import 'package:appflowy/shared/feedback_gesture_detector.dart';
|
||||
import 'package:appflowy/shared/flowy_gradient_colors.dart';
|
||||
import 'package:appflowy/shared/permission/permission_checker.dart';
|
||||
import 'package:appflowy/user/application/user_service.dart';
|
||||
import 'package:appflowy/util/string_extension.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:appflowy_result/appflowy_result.dart';
|
||||
@ -19,6 +24,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/snap_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
class PageStyleCoverImage extends StatelessWidget {
|
||||
@ -33,13 +39,11 @@ class PageStyleCoverImage extends StatelessWidget {
|
||||
final backgroundColor = context.pageStyleBackgroundColor;
|
||||
return BlocBuilder<DocumentPageStyleBloc, DocumentPageStyleState>(
|
||||
builder: (context, state) {
|
||||
return Row(
|
||||
return Column(
|
||||
children: [
|
||||
_buildOptionGroup(
|
||||
context,
|
||||
backgroundColor,
|
||||
state,
|
||||
),
|
||||
_buildOptionGroup(context, backgroundColor, state),
|
||||
const VSpace(16.0),
|
||||
_buildPreview(context, state),
|
||||
],
|
||||
);
|
||||
},
|
||||
@ -51,46 +55,124 @@ class PageStyleCoverImage extends StatelessWidget {
|
||||
Color backgroundColor,
|
||||
DocumentPageStyleState state,
|
||||
) {
|
||||
return Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: const BorderRadius.horizontal(
|
||||
left: Radius.circular(12),
|
||||
right: Radius.circular(12),
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: const BorderRadius.horizontal(
|
||||
left: Radius.circular(12),
|
||||
right: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Row(
|
||||
children: [
|
||||
_CoverOptionButton(
|
||||
showLeftCorner: true,
|
||||
showRightCorner: false,
|
||||
selected: state.coverImage.isPresets,
|
||||
onTap: () => _showPresets(context),
|
||||
child: const _PresetCover(),
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Row(
|
||||
children: [
|
||||
_CoverOptionButton(
|
||||
showLeftCorner: true,
|
||||
showRightCorner: false,
|
||||
selected: state.coverImage.isPresets,
|
||||
onTap: () => _showPresets(context),
|
||||
child: const _PresetCover(),
|
||||
),
|
||||
_CoverOptionButton(
|
||||
showLeftCorner: false,
|
||||
showRightCorner: false,
|
||||
selected: state.coverImage.isPhoto,
|
||||
onTap: () => _pickImage(context),
|
||||
child: const _PhotoCover(),
|
||||
),
|
||||
_CoverOptionButton(
|
||||
showLeftCorner: false,
|
||||
showRightCorner: true,
|
||||
selected: state.coverImage.isUnsplashImage,
|
||||
onTap: () => _showUnsplash(context),
|
||||
child: const _UnsplashCover(),
|
||||
),
|
||||
],
|
||||
),
|
||||
_CoverOptionButton(
|
||||
showLeftCorner: false,
|
||||
showRightCorner: false,
|
||||
selected: state.coverImage.isPhoto,
|
||||
onTap: () => _pickImage(context),
|
||||
child: const _PhotoCover(),
|
||||
),
|
||||
_CoverOptionButton(
|
||||
showLeftCorner: false,
|
||||
showRightCorner: true,
|
||||
selected: state.coverImage.isUnsplashImage,
|
||||
onTap: () => _showUnsplash(context),
|
||||
child: const _UnsplashCover(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPreview(
|
||||
BuildContext context,
|
||||
DocumentPageStyleState state,
|
||||
) {
|
||||
final cover = state.coverImage;
|
||||
if (cover.isNone) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final value = cover.value;
|
||||
final type = cover.type;
|
||||
|
||||
Widget preview = const SizedBox.shrink();
|
||||
|
||||
if (type == PageStyleCoverImageType.customImage ||
|
||||
type == PageStyleCoverImageType.unsplashImage) {
|
||||
final userProfilePB =
|
||||
context.read<MobileViewPageBloc>().state.userProfilePB;
|
||||
preview = FlowyNetworkImage(
|
||||
url: value,
|
||||
userProfilePB: userProfilePB,
|
||||
);
|
||||
}
|
||||
|
||||
if (type == PageStyleCoverImageType.builtInImage) {
|
||||
preview = Image.asset(
|
||||
PageStyleCoverImageType.builtInImagePath(value),
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
}
|
||||
|
||||
if (type == PageStyleCoverImageType.pureColor) {
|
||||
final color = value.coverColor(context);
|
||||
if (color != null) {
|
||||
preview = ColoredBox(
|
||||
color: color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (type == PageStyleCoverImageType.gradientColor) {
|
||||
preview = Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: FlowyGradientColor.fromId(value).linear,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (type == PageStyleCoverImageType.localImage) {
|
||||
preview = Image.file(
|
||||
File(value),
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
}
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
FlowyText(LocaleKeys.pageStyle_image.tr()),
|
||||
const Spacer(),
|
||||
Container(
|
||||
width: 40,
|
||||
height: 28,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(6.0)),
|
||||
border: Border.all(color: const Color(0x1F222533)),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(5.0)),
|
||||
child: preview,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _showPresets(BuildContext context) {
|
||||
final pageStyleBloc = context.read<DocumentPageStyleBloc>();
|
||||
|
||||
context.pop();
|
||||
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showDragHandle: true,
|
||||
@ -99,18 +181,18 @@ class PageStyleCoverImage extends StatelessWidget {
|
||||
showHeader: true,
|
||||
showRemoveButton: true,
|
||||
onRemove: () {
|
||||
context.read<DocumentPageStyleBloc>().add(
|
||||
DocumentPageStyleEvent.updateCoverImage(
|
||||
PageStyleCover.none(),
|
||||
),
|
||||
);
|
||||
pageStyleBloc.add(
|
||||
DocumentPageStyleEvent.updateCoverImage(
|
||||
PageStyleCover.none(),
|
||||
),
|
||||
);
|
||||
},
|
||||
title: LocaleKeys.pageStyle_pageCover.tr(),
|
||||
title: LocaleKeys.pageStyle_presets.tr(),
|
||||
barrierColor: Colors.transparent,
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
builder: (_) {
|
||||
return BlocProvider.value(
|
||||
value: context.read<DocumentPageStyleBloc>(),
|
||||
value: pageStyleBloc,
|
||||
child: const PageCoverBottomSheet(),
|
||||
);
|
||||
},
|
||||
@ -174,6 +256,9 @@ class PageStyleCoverImage extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _showUnsplash(BuildContext context) {
|
||||
final pageStyleBloc = context.read<DocumentPageStyleBloc>();
|
||||
context.pop();
|
||||
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showDragHandle: true,
|
||||
@ -181,15 +266,15 @@ class PageStyleCoverImage extends StatelessWidget {
|
||||
showDoneButton: true,
|
||||
showHeader: true,
|
||||
showRemoveButton: true,
|
||||
title: LocaleKeys.pageStyle_coverImage.tr(),
|
||||
title: LocaleKeys.pageStyle_unsplash.tr(),
|
||||
barrierColor: Colors.transparent,
|
||||
backgroundColor: Theme.of(context).colorScheme.background,
|
||||
onRemove: () {
|
||||
context.read<DocumentPageStyleBloc>().add(
|
||||
DocumentPageStyleEvent.updateCoverImage(
|
||||
PageStyleCover.none(),
|
||||
),
|
||||
);
|
||||
pageStyleBloc.add(
|
||||
DocumentPageStyleEvent.updateCoverImage(
|
||||
PageStyleCover.none(),
|
||||
),
|
||||
);
|
||||
},
|
||||
builder: (_) {
|
||||
return ConstrainedBox(
|
||||
@ -204,14 +289,14 @@ class PageStyleCoverImage extends StatelessWidget {
|
||||
child: UnsplashImageWidget(
|
||||
type: UnsplashImageType.fullScreen,
|
||||
onSelectUnsplashImage: (url) {
|
||||
context.read<DocumentPageStyleBloc>().add(
|
||||
DocumentPageStyleEvent.updateCoverImage(
|
||||
PageStyleCover(
|
||||
type: PageStyleCoverImageType.unsplashImage,
|
||||
value: url,
|
||||
),
|
||||
),
|
||||
);
|
||||
pageStyleBloc.add(
|
||||
DocumentPageStyleEvent.updateCoverImage(
|
||||
PageStyleCover(
|
||||
type: PageStyleCoverImageType.unsplashImage,
|
||||
value: url,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -308,6 +393,7 @@ class _CoverOptionButton extends StatelessWidget {
|
||||
duration: Durations.medium1,
|
||||
decoration: selected
|
||||
? ShapeDecoration(
|
||||
color: const Color(0x141AC3F2),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: const BorderSide(
|
||||
width: 1.50,
|
||||
|
@ -11,8 +11,9 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_emoji_mart/flutter_emoji_mart.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class PageStyleIcon extends StatelessWidget {
|
||||
class PageStyleIcon extends StatefulWidget {
|
||||
const PageStyleIcon({
|
||||
super.key,
|
||||
required this.view,
|
||||
@ -20,10 +21,15 @@ class PageStyleIcon extends StatelessWidget {
|
||||
|
||||
final ViewPB view;
|
||||
|
||||
@override
|
||||
State<PageStyleIcon> createState() => _PageStyleIconState();
|
||||
}
|
||||
|
||||
class _PageStyleIconState extends State<PageStyleIcon> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (_) => PageStyleIconBloc(view: view)
|
||||
create: (_) => PageStyleIconBloc(view: widget.view)
|
||||
..add(const PageStyleIconEvent.initial()),
|
||||
child: BlocBuilder<PageStyleIconBloc, PageStyleIconState>(
|
||||
builder: (context, state) {
|
||||
@ -60,6 +66,10 @@ class PageStyleIcon extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _showIconSelector(BuildContext context, String selectedIcon) {
|
||||
context.pop();
|
||||
|
||||
final pageStyleIconBloc = PageStyleIconBloc(view: widget.view)
|
||||
..add(const PageStyleIconEvent.initial());
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showDragHandle: true,
|
||||
@ -75,13 +85,13 @@ class PageStyleIcon extends StatelessWidget {
|
||||
initialChildSize: 0.61,
|
||||
showRemoveButton: true,
|
||||
onRemove: () {
|
||||
context.read<PageStyleIconBloc>().add(
|
||||
const PageStyleIconEvent.updateIcon('', true),
|
||||
);
|
||||
pageStyleIconBloc.add(
|
||||
const PageStyleIconEvent.updateIcon('', true),
|
||||
);
|
||||
},
|
||||
scrollableWidgetBuilder: (_, controller) {
|
||||
return BlocProvider.value(
|
||||
value: context.read<PageStyleIconBloc>(),
|
||||
value: pageStyleIconBloc,
|
||||
child: Expanded(
|
||||
child: Scrollbar(
|
||||
controller: controller,
|
||||
@ -112,6 +122,8 @@ class _IconSelectorState extends State<_IconSelector> {
|
||||
EmojiData? emojiData;
|
||||
List<String> availableEmojis = [];
|
||||
|
||||
PageStyleIconBloc? pageStyleIconBloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -131,6 +143,14 @@ class _IconSelectorState extends State<_IconSelector> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
pageStyleIconBloc = context.read<PageStyleIconBloc>();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
pageStyleIconBloc?.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
@ -146,7 +166,7 @@ class _IconSelectorState extends State<_IconSelector> {
|
||||
_buildSearchBar(context),
|
||||
Expanded(
|
||||
child: GridView.count(
|
||||
crossAxisCount: _getEmojiPerLine(context),
|
||||
crossAxisCount: 7,
|
||||
controller: widget.scrollController,
|
||||
children: [
|
||||
for (final emoji in availableEmojis)
|
||||
@ -165,27 +185,33 @@ class _IconSelectorState extends State<_IconSelector> {
|
||||
String emoji,
|
||||
String? selectedEmoji,
|
||||
) {
|
||||
Widget child = Center(
|
||||
child: FlowyText.emoji(
|
||||
emoji,
|
||||
fontSize: 24,
|
||||
Widget child = SizedBox.square(
|
||||
dimension: 24.0,
|
||||
child: Center(
|
||||
child: FlowyText.emoji(
|
||||
emoji,
|
||||
fontSize: 24,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (emoji == selectedEmoji) {
|
||||
child = Container(
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
decoration: ShapeDecoration(
|
||||
shape: RoundedRectangleBorder(
|
||||
side: const BorderSide(
|
||||
width: 1.50,
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
color: Color(0xFF00BCF0),
|
||||
child = Center(
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: ShapeDecoration(
|
||||
shape: RoundedRectangleBorder(
|
||||
side: const BorderSide(
|
||||
width: 1.40,
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
color: Color(0xFF00BCF0),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(9),
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
@ -208,11 +234,6 @@ class _IconSelectorState extends State<_IconSelector> {
|
||||
return availableEmojis;
|
||||
}
|
||||
|
||||
int _getEmojiPerLine(BuildContext context) {
|
||||
final width = MediaQuery.of(context).size.width;
|
||||
return width ~/ 48.0; // the size of the emoji
|
||||
}
|
||||
|
||||
Widget _buildSearchBar(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
|
@ -11,6 +11,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
const kPageStyleLayoutHeight = 52.0;
|
||||
|
||||
@ -117,6 +118,7 @@ class _OptionGroup<T> extends StatelessWidget {
|
||||
duration: Durations.medium1,
|
||||
decoration: selected
|
||||
? ShapeDecoration(
|
||||
color: const Color(0x141AC3F2),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: const BorderSide(
|
||||
width: 1.50,
|
||||
@ -180,7 +182,10 @@ class _FontButton extends StatelessWidget {
|
||||
const HSpace(16.0),
|
||||
FlowyText(LocaleKeys.titleBar_font.tr()),
|
||||
const Spacer(),
|
||||
FlowyText(fontFamilyDisplayName),
|
||||
FlowyText(
|
||||
fontFamilyDisplayName,
|
||||
color: context.pageStyleTextColor,
|
||||
),
|
||||
const HSpace(6.0),
|
||||
const FlowySvg(FlowySvgs.m_page_style_arrow_right_s),
|
||||
const HSpace(12.0),
|
||||
@ -193,6 +198,9 @@ class _FontButton extends StatelessWidget {
|
||||
}
|
||||
|
||||
void _showFontSelector(BuildContext context) {
|
||||
final pageStyleBloc = context.read<DocumentPageStyleBloc>();
|
||||
context.pop();
|
||||
|
||||
showMobileBottomSheet(
|
||||
context,
|
||||
showDragHandle: true,
|
||||
@ -208,7 +216,7 @@ class _FontButton extends StatelessWidget {
|
||||
initialChildSize: 0.61,
|
||||
scrollableWidgetBuilder: (_, controller) {
|
||||
return BlocProvider.value(
|
||||
value: context.read<DocumentPageStyleBloc>(),
|
||||
value: pageStyleBloc,
|
||||
child: BlocBuilder<DocumentPageStyleBloc, DocumentPageStyleState>(
|
||||
builder: (context, state) {
|
||||
return Expanded(
|
||||
@ -219,11 +227,11 @@ class _FontButton extends StatelessWidget {
|
||||
selectedFontFamilyName:
|
||||
state.fontFamily ?? defaultFontFamily,
|
||||
onFontFamilySelected: (fontFamilyName) {
|
||||
context.read<DocumentPageStyleBloc>().add(
|
||||
DocumentPageStyleEvent.updateFontFamily(
|
||||
fontFamilyName,
|
||||
),
|
||||
);
|
||||
pageStyleBloc.add(
|
||||
DocumentPageStyleEvent.updateFontFamily(
|
||||
fontFamilyName,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -25,7 +25,7 @@ class PageStyleBottomSheet extends StatelessWidget {
|
||||
children: [
|
||||
// cover image
|
||||
FlowyText(
|
||||
LocaleKeys.pageStyle_backgroundImage.tr(),
|
||||
LocaleKeys.pageStyle_coverImage.tr(),
|
||||
color: context.pageStyleTextColor,
|
||||
fontSize: 14.0,
|
||||
),
|
||||
|
@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 0.5.6
|
||||
version: 0.5.7
|
||||
|
||||
environment:
|
||||
flutter: ">=3.19.0"
|
||||
|
@ -1,5 +1,5 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="icon_left_outlined">
|
||||
<path id="Union" d="M13.5774 1.9107C13.9028 2.23614 13.9028 2.76378 13.5774 3.08921L6.66667 9.99996L13.5774 16.9107C13.9028 17.2361 13.9028 17.7638 13.5774 18.0892C13.252 18.4147 12.7243 18.4147 12.3989 18.0892L5.48816 11.1785C4.83728 10.5276 4.83728 9.47232 5.48816 8.82145L12.3989 1.9107C12.7243 1.58527 13.252 1.58527 13.5774 1.9107Z" fill="#2B2F36"/>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.8">
|
||||
<path d="M15.0796 19.9001L8.57604 13.3966C7.80799 12.6285 7.80799 11.3717 8.57604 10.6036L15.0796 4.1001" stroke="black" stroke-width="1.49621" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 491 B After Width: | Height: | Size: 342 B |
@ -1611,7 +1611,8 @@
|
||||
"photoPermissionDescription": "Allow access to the photo library for uploading images.",
|
||||
"openSettings": "Open Settings",
|
||||
"photoPermissionTitle": "AppFlowy Would Like to Access Your Photo Library",
|
||||
"doNotAllow": "Don't Allow"
|
||||
"doNotAllow": "Don't Allow",
|
||||
"image": "Image"
|
||||
},
|
||||
"commandPalette": {
|
||||
"placeholder": "Type to search for views...",
|
||||
|
Loading…
Reference in New Issue
Block a user