Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
woin2ee committed Feb 5, 2025
2 parents d841462 + c009487 commit e2e1cb8
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 223 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/deploy_by_tag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Deploy by tag

on:
push:
tags:
- '*.*.*'

jobs:
deploy_web_by_tag:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/[email protected]
with:
ref: ${{ github.ref_name }}
- name: Flutter action
uses: subosito/[email protected]
with:
channel: stable
- run: flutter --version
- name: Build for web release
env:
BASE_HREF: "/DST-Helper-web/"
run: |
flutter pub get
dart run build_runner build
flutter build web --base-href "${BASE_HREF}"
- name: Move to build dir for web
run: cd build/web
- name: Push directory to another repository
uses: cpina/[email protected]
env:
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
with:
source-directory: 'build/web'
destination-github-username: 'woin2ee'
destination-repository-name: 'DST-Helper-web'
user-email: [email protected]
target-branch: main
commit-message: "Deploy ${{ github.ref_name }}"
137 changes: 2 additions & 135 deletions lib/cook_page/cook_page.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import 'package:dst_helper/cook_page/recipe_card/recipe_card.dart';
import 'package:dst_helper/cook_page/recipe_card_table.dart';
import 'package:dst_helper/cook_page/recipe_list/recipe_list.dart';
import 'package:dst_helper/models/v2/item/item.dart';
import 'package:flutter/material.dart';

class CookPage extends StatefulWidget {
const CookPage({super.key});

static const double topBarHeight = 50;

@override
State<CookPage> createState() => _CookPageState();
}
Expand All @@ -21,141 +18,11 @@ class _CookPageState extends State<CookPage> {
spacing: 10,
children: [
const Expanded(
child: _RecipeCardTable(),
child: RecipeCardTable(),
),
RecipeList(),
],
),
);
}
}

class _RecipeCardTable extends StatefulWidget {
const _RecipeCardTable();

@override
State<_RecipeCardTable> createState() => _RecipeCardTableState();
}

class _RecipeCardTableState extends State<_RecipeCardTable> {
RecipeCardMode _recipeCardMode = RecipeCardMode.basic;

@override
Widget build(BuildContext context) {
return Stack(
children: [
ConstrainedBox(
constraints: const BoxConstraints.expand(),
child: SingleChildScrollView(
padding: const EdgeInsets.only(top: 36 + CookPage.topBarHeight, left: 42, right: 42, bottom: 36),
child: Center(
child: Wrap(
spacing: 40,
runSpacing: 40,
children: [
...Items.recipes.map((recipe) {
switch (_recipeCardMode) {
case RecipeCardMode.basic:
return DefaultRecipeCard(recipe: recipe);
case RecipeCardMode.detail:
return DetailRecipeCard(recipe: recipe);
case RecipeCardMode.simple:
return SimpleRecipeCard(recipe: recipe);
case RecipeCardMode.onlyImage:
return OnlyImageRecipeCard(recipe: recipe);
}
}),
],
),
),
),
),
Container(
height: CookPage.topBarHeight,
margin: const EdgeInsets.only(left: 12, right: 20),
padding: const EdgeInsets.only(top: 8, bottom: 8),
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: Colors.black12,
),
),
color: Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
color: Colors.red.withOpacity(0),
width: 400,
), // TODO: Implement a search bar
_ModeChangeSwitch(
mode: _recipeCardMode,
onChangedMode: (mode) => setState(() {
_recipeCardMode = mode;
}),
),
],
),
),
],
);
}
}

class _ModeChangeSwitch extends StatefulWidget {
const _ModeChangeSwitch({
required this.mode,
required this.onChangedMode,
});

final RecipeCardMode mode;
final void Function(RecipeCardMode)? onChangedMode;

@override
State<_ModeChangeSwitch> createState() => _ModeChangeSwitchState();
}

class _ModeChangeSwitchState extends State<_ModeChangeSwitch> {
static const _order = [
RecipeCardMode.basic,
RecipeCardMode.detail,
RecipeCardMode.simple,
RecipeCardMode.onlyImage,
];

final List<bool> _selectedModes = List.filled(_order.length, false);

@override
void initState() {
super.initState();
_updateState();
}

@override
void didUpdateWidget(covariant _ModeChangeSwitch oldWidget) {
super.didUpdateWidget(oldWidget);
_updateState();
}

void _updateState() {
_selectedModes.setAll(0, List.filled(_order.length, false));
var index = _order.indexOf(widget.mode);
_selectedModes[index] = true;
}

@override
Widget build(BuildContext context) {
return ToggleButtons(
borderRadius: const BorderRadius.all(Radius.circular(12)),
onPressed: (index) {
var selectedMode = _order[index];
widget.onChangedMode?.call(selectedMode);
},
constraints: const BoxConstraints(minWidth: 64, minHeight: 32),
isSelected: _selectedModes,
children: [..._order.map((mode) => Text(mode.name))],
);
}
}
160 changes: 160 additions & 0 deletions lib/cook_page/recipe_card_table.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import 'package:dst_helper/cook_page/recipe_card/recipe_card.dart';
import 'package:dst_helper/cook_page/recipe_card_table_model.dart';
import 'package:flutter/material.dart';

class RecipeCardTable extends StatefulWidget {
const RecipeCardTable({super.key});

static const double topBarHeight = 50;

@override
State<RecipeCardTable> createState() => _RecipeCardTableState();
}

class _RecipeCardTableState extends State<RecipeCardTable> {
final RecipeCardTableModel model = RecipeCardTableModel();

@override
Widget build(BuildContext context) {
return Stack(
children: [
ConstrainedBox(
constraints: const BoxConstraints.expand(),
child: SingleChildScrollView(
padding: const EdgeInsets.only(top: 36 + RecipeCardTable.topBarHeight, left: 42, right: 42, bottom: 36),
child: Center(
child: ListenableBuilder(
listenable: model,
builder: (context, child) {
return Wrap(
spacing: 40,
runSpacing: 40,
children: [
...model.getRecipes(context).map((recipe) {
switch (model.recipeCardMode) {
case RecipeCardMode.basic:
return DefaultRecipeCard(recipe: recipe);
case RecipeCardMode.detail:
return DetailRecipeCard(recipe: recipe);
case RecipeCardMode.simple:
return SimpleRecipeCard(recipe: recipe);
case RecipeCardMode.onlyImage:
return OnlyImageRecipeCard(recipe: recipe);
}
}),
],
);
}),
),
),
),
_TopBar(model: model),
],
);
}
}

class _TopBar extends StatelessWidget {
_TopBar({
required this.model,
});

final RecipeCardTableModel model;

final _searchKeywordController = TextEditingController();

@override
Widget build(BuildContext context) {
return Container(
height: RecipeCardTable.topBarHeight,
margin: const EdgeInsets.only(left: 12, right: 20),
padding: const EdgeInsets.only(top: 8, bottom: 8),
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: Colors.black12,
),
),
color: Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SearchBar(
constraints: const BoxConstraints(maxWidth: 400),
padding: const WidgetStatePropertyAll(EdgeInsets.only(left: 8, right: 2)),
controller: _searchKeywordController,
elevation: const WidgetStatePropertyAll(2),
shape: const WidgetStatePropertyAll(
RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8)),
),
),
onSubmitted: (text) => model.searchKeyword = text,
leading: const Icon(Icons.search),
trailing: [
IconButton(
iconSize: 18,
constraints: const BoxConstraints(minWidth: 30, minHeight: 30),
onPressed: () {
_searchKeywordController.text = '';
model.searchKeyword = '';
},
icon: const Icon(Icons.clear),
),
],
),
_ModeChangeSwitch(
model: model,
),
],
),
);
}
}

class _ModeChangeSwitch extends StatefulWidget {
const _ModeChangeSwitch({
required this.model,
});

final RecipeCardTableModel model;

@override
State<_ModeChangeSwitch> createState() => _ModeChangeSwitchState();
}

class _ModeChangeSwitchState extends State<_ModeChangeSwitch> {
static const _order = [
RecipeCardMode.basic,
RecipeCardMode.detail,
RecipeCardMode.simple,
RecipeCardMode.onlyImage,
];

final List<bool> _selectedModes = List.filled(_order.length, false);

@override
void initState() {
super.initState();
var index = _order.indexOf(widget.model.recipeCardMode);
_selectedModes[index] = true;
}

@override
Widget build(BuildContext context) {
return ToggleButtons(
borderRadius: const BorderRadius.all(Radius.circular(12)),
onPressed: (index) => setState(() {
for (int i = 0; i < _selectedModes.length; i++) {
_selectedModes[i] = i == index;
}
widget.model.recipeCardMode = _order[index];
}),
constraints: const BoxConstraints(minWidth: 64, minHeight: 32),
isSelected: _selectedModes,
children: [..._order.map((mode) => Text(mode.name))],
);
}
}
36 changes: 36 additions & 0 deletions lib/cook_page/recipe_card_table_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:dst_helper/cook_page/recipe_card/recipe_card.dart';
import 'package:dst_helper/l10n/l10ns.dart';
import 'package:dst_helper/models/v2/item/item.dart';
import 'package:flutter/material.dart';

class RecipeCardTableModel extends ChangeNotifier {
RecipeCardMode _recipeCardMode = RecipeCardMode.basic;
RecipeCardMode get recipeCardMode => _recipeCardMode;
set recipeCardMode(RecipeCardMode value) {
_recipeCardMode = value;
notifyListeners();
}

String _searchKeyword = '';
set searchKeyword(String value) {
_searchKeyword = value;
notifyListeners();
}

List<Recipe> getRecipes(BuildContext context) {
var entireRecipes = Items.recipes;

if (_searchKeyword.isEmpty) {
return entireRecipes;
}

var searchedRecipes = entireRecipes.where((recipe) {
var recipeName = L10ns.of(context).localized('${recipe.code}_name');
var adjustedName = recipeName.replaceAll(' ', '').toLowerCase();
var searchKeyword = _searchKeyword.toLowerCase();
return adjustedName.contains(searchKeyword);
});

return searchedRecipes.toList();
}
}
Loading

0 comments on commit e2e1cb8

Please sign in to comment.