small changes
This commit is contained in:
@@ -304,8 +304,9 @@ class FilcAPI {
|
||||
}
|
||||
} on Exception catch (error, stacktrace) {
|
||||
log("ERROR: FilcAPI.getAllSharedThemes: $error $stacktrace");
|
||||
// return empty array if error
|
||||
return [];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<int> addSharedGradeColors(SharedGradeColors gradeColors) async {
|
||||
|
||||
@@ -7,6 +7,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
List? _cachedThemesJson;
|
||||
|
||||
class ShareProvider extends ChangeNotifier {
|
||||
final UserProvider _user;
|
||||
|
||||
@@ -101,50 +103,59 @@ class ShareProvider extends ChangeNotifier {
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<List<SharedTheme>> getAllPublicThemes(BuildContext context,
|
||||
{int count = 0}) async {
|
||||
List? themesJson = await FilcAPI.getAllSharedThemes(count);
|
||||
Future<List<SharedTheme>> getAllPublicThemes(BuildContext context,
|
||||
{int offset = 0, int limit = 10}) async {
|
||||
// Fetch all themes only once if not already fetched
|
||||
if (_cachedThemesJson == null) {
|
||||
_cachedThemesJson = await FilcAPI.getAllSharedThemes(0);
|
||||
}
|
||||
|
||||
List<SharedTheme> themes = [];
|
||||
List<SharedTheme> themes = [];
|
||||
|
||||
if (themesJson != null) {
|
||||
for (var t in themesJson) {
|
||||
if (t['public_id'].toString().replaceAll(' ', '') == '') continue;
|
||||
if (t['grade_colors_id'].toString().replaceAll(' ', '') == '') continue;
|
||||
if (_cachedThemesJson != null) {
|
||||
// Get the current chunk based on offset and limit
|
||||
final int endIndex = (offset + limit <= _cachedThemesJson!.length)
|
||||
? offset + limit
|
||||
: _cachedThemesJson!.length;
|
||||
final chunk = _cachedThemesJson!.sublist(offset, endIndex);
|
||||
|
||||
Map? gradeColorsJson =
|
||||
await FilcAPI.getSharedGradeColors(t['grade_colors_id']);
|
||||
for (var t in chunk) {
|
||||
if (t['public_id'].toString().replaceAll(' ', '') == '') continue;
|
||||
if (t['grade_colors_id'].toString().replaceAll(' ', '') == '') continue;
|
||||
|
||||
if (gradeColorsJson != null) {
|
||||
SharedTheme theme = SharedTheme.fromJson(
|
||||
t,
|
||||
SharedGradeColors.fromJson(gradeColorsJson["public_id"] != ''
|
||||
? gradeColorsJson
|
||||
: {
|
||||
"public_id": "0",
|
||||
"is_public": false,
|
||||
"nickname": "Anonymous",
|
||||
"five_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[4].value,
|
||||
"four_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[3].value,
|
||||
"three_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[2].value,
|
||||
"two_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[1].value,
|
||||
"one_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[0].value,
|
||||
}),
|
||||
);
|
||||
Map? gradeColorsJson =
|
||||
await FilcAPI.getSharedGradeColors(t['grade_colors_id']);
|
||||
|
||||
themes.add(theme);
|
||||
}
|
||||
if (gradeColorsJson != null) {
|
||||
SharedTheme theme = SharedTheme.fromJson(
|
||||
t,
|
||||
SharedGradeColors.fromJson(gradeColorsJson["public_id"] != ''
|
||||
? gradeColorsJson
|
||||
: {
|
||||
"public_id": "0",
|
||||
"is_public": false,
|
||||
"nickname": "Anonymous",
|
||||
"five_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[4].value,
|
||||
"four_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[3].value,
|
||||
"three_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[2].value,
|
||||
"two_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[1].value,
|
||||
"one_color":
|
||||
SettingsProvider.defaultSettings().gradeColors[0].value,
|
||||
}),
|
||||
);
|
||||
|
||||
themes.add(theme);
|
||||
}
|
||||
}
|
||||
|
||||
return themes;
|
||||
}
|
||||
|
||||
return themes;
|
||||
}
|
||||
|
||||
// grade colors
|
||||
Future<(SharedGradeColors?, int)> shareCurrentGradeColors(
|
||||
BuildContext context, {
|
||||
|
||||
@@ -9,12 +9,11 @@ List<String> faces = [
|
||||
"(o^▽^o)",
|
||||
"(⌒▽⌒)☆",
|
||||
"( ̄ω ̄)",
|
||||
"(≧◡≦)",
|
||||
"(◕‿◕)",
|
||||
"(⌒‿⌒)",
|
||||
"(◕ω◕)",
|
||||
"(⌒ω⌒)",
|
||||
"(☆ω☆)",
|
||||
"(^ヮ^)/",
|
||||
"(⁀ᗢ⁀)",
|
||||
"(^ᗢ^)",
|
||||
"(≧ω≦)",
|
||||
"(/ω\)",
|
||||
"(//▽//)",
|
||||
@@ -26,10 +25,8 @@ List<String> faces = [
|
||||
"(・ω・)ノ",
|
||||
"(=^・ω・^=)",
|
||||
"( =ω= )",
|
||||
"( ͡° ͜ʖ ͡°)",
|
||||
"( ͡• ͜ʖ ͡• )",
|
||||
"(◕‿◕✿)",
|
||||
"(✿◠‿◠)"
|
||||
"(◕ω◕✿)",
|
||||
"(✿◠ω◠)"
|
||||
];
|
||||
|
||||
class Empty extends StatelessWidget {
|
||||
|
||||
@@ -31,13 +31,9 @@ class MenuPaintList extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PanelButton(
|
||||
onPressed: () async {
|
||||
List<SharedTheme> publicThemes =
|
||||
await Provider.of<ShareProvider>(context, listen: false)
|
||||
.getAllPublicThemes(context);
|
||||
|
||||
Navigator.of(context, rootNavigator: true).push(CupertinoPageRoute(
|
||||
builder: (context) => PaintListScreen(publicThemes: publicThemes)));
|
||||
onPressed: () {
|
||||
Navigator.of(context, rootNavigator: true).push(
|
||||
CupertinoPageRoute(builder: (context) => const PaintListScreen()));
|
||||
},
|
||||
title: Text(
|
||||
"own_paints".i18n,
|
||||
@@ -61,9 +57,7 @@ class MenuPaintList extends StatelessWidget {
|
||||
}
|
||||
|
||||
class PaintListScreen extends StatefulWidget {
|
||||
const PaintListScreen({super.key, required this.publicThemes});
|
||||
|
||||
final List<SharedTheme> publicThemes;
|
||||
const PaintListScreen({super.key});
|
||||
|
||||
@override
|
||||
PaintListScreenState createState() => PaintListScreenState();
|
||||
@@ -74,42 +68,80 @@ class PaintListScreenState extends State<PaintListScreen>
|
||||
late SettingsProvider settingsProvider;
|
||||
late UserProvider user;
|
||||
late ShareProvider shareProvider;
|
||||
|
||||
late AnimationController _hideContainersController;
|
||||
|
||||
late List<Widget> tiles;
|
||||
|
||||
final _paintId = TextEditingController();
|
||||
|
||||
SharedTheme? newThemeByID;
|
||||
List<SharedTheme> publicThemes = [];
|
||||
List<Widget> tiles = [];
|
||||
bool isLoading = false;
|
||||
bool hasMore = true;
|
||||
int currentOffset = 0;
|
||||
static const int pageSize = 10;
|
||||
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
shareProvider = Provider.of<ShareProvider>(context, listen: false);
|
||||
|
||||
_hideContainersController = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 200));
|
||||
|
||||
_scrollController.addListener(_scrollListener);
|
||||
_loadMoreThemes();
|
||||
}
|
||||
|
||||
void buildPublicPaintTiles() async {
|
||||
List<Widget> subjectTiles = [];
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.dispose();
|
||||
_hideContainersController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
var added = [];
|
||||
var i = 0;
|
||||
void _scrollListener() {
|
||||
if (_scrollController.position.pixels >=
|
||||
_scrollController.position.maxScrollExtent * 0.8) {
|
||||
_loadMoreThemes();
|
||||
}
|
||||
}
|
||||
|
||||
for (var t in widget.publicThemes) {
|
||||
if (added.contains(t.id)) continue;
|
||||
Future<void> _loadMoreThemes() async {
|
||||
if (isLoading || !hasMore) return;
|
||||
|
||||
Widget w = PanelButton(
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final newThemes = await shareProvider.getAllPublicThemes(
|
||||
context,
|
||||
offset: currentOffset,
|
||||
limit: pageSize,
|
||||
);
|
||||
|
||||
setState(() {
|
||||
publicThemes.addAll(newThemes);
|
||||
currentOffset += newThemes.length;
|
||||
hasMore = newThemes.length == pageSize;
|
||||
isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void buildPublicPaintTiles() {
|
||||
tiles = []; // Clear existing tiles
|
||||
|
||||
for (var i = 0; i < publicThemes.length; i++) {
|
||||
final t = publicThemes[i];
|
||||
tiles.add(PanelButton(
|
||||
onPressed: () async {
|
||||
newThemeByID = t;
|
||||
|
||||
// slay
|
||||
|
||||
setPaint();
|
||||
|
||||
setState(() {});
|
||||
},
|
||||
title: Column(
|
||||
@@ -162,231 +194,24 @@ class PaintListScreenState extends State<PaintListScreen>
|
||||
),
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(i == 0 ? 12.0 : 4.0),
|
||||
bottom:
|
||||
Radius.circular(i + 1 == widget.publicThemes.length ? 12.0 : 4.0),
|
||||
bottom: Radius.circular(
|
||||
i + 1 == publicThemes.length && !hasMore ? 12.0 : 4.0),
|
||||
),
|
||||
);
|
||||
|
||||
i += 1;
|
||||
subjectTiles.add(w);
|
||||
added.add(t.id);
|
||||
}
|
||||
|
||||
if (widget.publicThemes.isEmpty) {
|
||||
subjectTiles.add(Empty(
|
||||
subtitle: 'no_pub_paint'.i18n,
|
||||
));
|
||||
}
|
||||
|
||||
tiles = subjectTiles;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
settingsProvider = Provider.of<SettingsProvider>(context);
|
||||
user = Provider.of<UserProvider>(context);
|
||||
|
||||
buildPublicPaintTiles();
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: _hideContainersController,
|
||||
builder: (context, child) => Opacity(
|
||||
opacity: 1 - _hideContainersController.value,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
leading: BackButton(color: AppColors.of(context).text),
|
||||
title: Text(
|
||||
"own_paints".i18n,
|
||||
style: TextStyle(color: AppColors.of(context).text),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
|
||||
child: Column(
|
||||
children: [
|
||||
// enter id
|
||||
SplittedPanel(
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(3.0),
|
||||
hasBorder: true,
|
||||
isTransparent: true,
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () => showEnterIDDialog(),
|
||||
title: Text(
|
||||
"enter_id".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withValues(alpha: .95),
|
||||
),
|
||||
),
|
||||
leading: Icon(
|
||||
FeatherIcons.plus,
|
||||
size: 22.0,
|
||||
color:
|
||||
AppColors.of(context).text.withValues(alpha: .95),
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12.0),
|
||||
bottom: Radius.circular(12.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(
|
||||
height: 18.0,
|
||||
),
|
||||
// current paint
|
||||
SplittedPanel(
|
||||
title: Text('current_paint'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () async {
|
||||
if (settingsProvider.currentThemeId != '') {
|
||||
Share.share(
|
||||
settingsProvider.currentThemeId,
|
||||
subject: 'share_subj_theme'.i18n,
|
||||
);
|
||||
} else {
|
||||
ShareThemeDialog.show(context);
|
||||
}
|
||||
},
|
||||
longPressInstead: true,
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
settingsProvider.currentThemeDisplayName != ''
|
||||
? settingsProvider.currentThemeDisplayName
|
||||
: 'no_name'.i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withValues(alpha: .95),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
settingsProvider.currentThemeCreator != ''
|
||||
? settingsProvider.currentThemeCreator
|
||||
: 'Anonymous',
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withValues(alpha: .65),
|
||||
fontSize: 15.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: Transform.translate(
|
||||
offset: const Offset(8.0, 0.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 2.0),
|
||||
width: 14.0,
|
||||
height: 14.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color:
|
||||
(settingsProvider.customBackgroundColor ??
|
||||
SettingsProvider.defaultSettings()
|
||||
.customBackgroundColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withValues(alpha: 0.15),
|
||||
offset: const Offset(1, 2),
|
||||
blurRadius: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(-4.0, 0.0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(left: 2.0),
|
||||
width: 14.0,
|
||||
height: 14.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: (settingsProvider
|
||||
.customHighlightColor ??
|
||||
SettingsProvider.defaultSettings()
|
||||
.customHighlightColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withValues(alpha: 0.15),
|
||||
offset: const Offset(1, 2),
|
||||
blurRadius: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(-8.0, 0.0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(left: 2.0),
|
||||
width: 14.0,
|
||||
height: 14.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: settingsProvider.customAccentColor ??
|
||||
accentColorMap[
|
||||
settingsProvider.accentColor],
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withValues(alpha: 0.15),
|
||||
offset: const Offset(1, 2),
|
||||
blurRadius: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(
|
||||
height: 18.0,
|
||||
),
|
||||
// own paints
|
||||
SplittedPanel(
|
||||
title: Text('public_paint'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
children: tiles,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isLoading) {
|
||||
tiles.add(const Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
if (publicThemes.isEmpty && !isLoading) {
|
||||
tiles.add(Empty(subtitle: 'no_pub_paint'.i18n, alwaysRandom: true));
|
||||
}
|
||||
}
|
||||
|
||||
// enter id dialog
|
||||
@@ -573,4 +398,185 @@ class PaintListScreenState extends State<PaintListScreen>
|
||||
Provider.of<ThemeModeObserver>(context, listen: false)
|
||||
.changeTheme(settingsProvider.theme, updateNavbarColor: true);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
settingsProvider = Provider.of<SettingsProvider>(context);
|
||||
user = Provider.of<UserProvider>(context);
|
||||
|
||||
buildPublicPaintTiles();
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: _hideContainersController,
|
||||
builder: (context, child) => Opacity(
|
||||
opacity: 1 - _hideContainersController.value,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
leading: BackButton(color: AppColors.of(context).text),
|
||||
title: Text(
|
||||
"own_paints".i18n,
|
||||
style: TextStyle(color: AppColors.of(context).text),
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
controller: _scrollController,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SplittedPanel(
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(3.0),
|
||||
hasBorder: true,
|
||||
isTransparent: true,
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () => showEnterIDDialog(),
|
||||
title: Text(
|
||||
"enter_id".i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withValues(alpha: .95),
|
||||
),
|
||||
),
|
||||
leading: Icon(
|
||||
FeatherIcons.plus,
|
||||
size: 22.0,
|
||||
color: AppColors.of(context).text.withValues(alpha: .95),
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12.0),
|
||||
bottom: Radius.circular(12.0),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 18.0),
|
||||
SplittedPanel(
|
||||
title: Text('current_paint'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
children: [
|
||||
PanelButton(
|
||||
onPressed: () async {
|
||||
if (settingsProvider.currentThemeId != '') {
|
||||
Share.share(
|
||||
settingsProvider.currentThemeId,
|
||||
subject: 'share_subj_theme'.i18n,
|
||||
);
|
||||
} else {
|
||||
ShareThemeDialog.show(context);
|
||||
}
|
||||
},
|
||||
longPressInstead: true,
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
settingsProvider.currentThemeDisplayName != ''
|
||||
? settingsProvider.currentThemeDisplayName
|
||||
: 'no_name'.i18n,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withValues(alpha: .95),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
settingsProvider.currentThemeCreator != ''
|
||||
? settingsProvider.currentThemeCreator
|
||||
: 'Anonymous',
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text.withValues(alpha: .65),
|
||||
fontSize: 15.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: Transform.translate(
|
||||
offset: const Offset(8.0, 0.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 2.0),
|
||||
width: 14.0,
|
||||
height: 14.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: (settingsProvider.customBackgroundColor ??
|
||||
SettingsProvider.defaultSettings().customBackgroundColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.of(context).text.withValues(alpha: 0.15),
|
||||
offset: const Offset(1, 2),
|
||||
blurRadius: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(-4.0, 0.0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(left: 2.0),
|
||||
width: 14.0,
|
||||
height: 14.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: (settingsProvider.customHighlightColor ??
|
||||
SettingsProvider.defaultSettings().customHighlightColor),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.of(context).text.withValues(alpha: 0.15),
|
||||
offset: const Offset(1, 2),
|
||||
blurRadius: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(-8.0, 0.0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(left: 2.0),
|
||||
width: 14.0,
|
||||
height: 14.0,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: settingsProvider.customAccentColor ??
|
||||
accentColorMap[settingsProvider.accentColor],
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.of(context).text.withValues(alpha: 0.15),
|
||||
offset: const Offset(1, 2),
|
||||
blurRadius: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
borderRadius: const BorderRadius.vertical(
|
||||
top: Radius.circular(12),
|
||||
bottom: Radius.circular(12),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 18.0),
|
||||
SplittedPanel(
|
||||
title: Text('public_paint'.i18n),
|
||||
padding: EdgeInsets.zero,
|
||||
cardPadding: const EdgeInsets.all(4.0),
|
||||
children: tiles,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user