Stacked-Org / stacked

A Flutter application architecture created from real world scenarios
MIT License
976 stars 255 forks source link

[bug]: Not render UI after app closed or lock screen or keep open long time then re-open it #1029

Closed Kimsoer closed 1 month ago

Kimsoer commented 1 year ago

Describe the bug

Dear be love team, Thank you so much for your good library,

And now I have one issue , my app is working with real time when keep app open a bit long time then the ui is not re-render the data. as the function request to api

Code in ViewModel : fetchData() async { try { setBusy(true); rebuildUi(); var response = await ApiProviderService().getRestClient().getGroupProductQty(); if (response.response.statusCode == 200 && response.response.data != null) { groupProductResponse = GroupProductsResponse.fromJson(response.data); } } catch (error) { GlobalFunction.onHttpRequestFail(error, this); } finally { setBusy(false); rebuildUi(); } }

To reproduce

Code in ViewModel : fetchData() async { try { setBusy(true); rebuildUi();

  var response = await ApiProviderService().getRestClient().getGroupProductQty();
  if (response.response.statusCode == 200 && response.response.data != null) {
    groupProductResponse = GroupProductsResponse.fromJson(response.data);
  }
} catch (error) {
  GlobalFunction.onHttpRequestFail(error, this);
} finally {
      setBusy(false);
  rebuildUi();
}

}

Code in View class SideBarWidget extends ViewModelWidget { const SideBarWidget({Key? key}) : super(key: key); @override Widget build(BuildContext context, HomeViewModel viewModel) { var data = viewModel.groupProductResponse.data?.products;

return (data?.isNotEmpty ?? false)
    ? Container(
        width: 120,
        height: MediaQuery.of(context).size.height,
        decoration: BoxDecoration(color: Theme.of(context).bgColorFF1E(context)),
        child: ListView.builder(
          itemCount: data?.length ?? 0,
          shrinkWrap: true,
          padding: const EdgeInsets.all(0),
          itemBuilder: (BuildContext context, int index) {
            var item = data?.elementAt(index);
            return GestureDetector(
              onTap: () {
                viewModel.setVisibleProduct(true);
                viewModel.groupProductDetail(item?.globalId ?? '');
              },
              child: Container(
                color: viewModel.selectGroupProduct == (item?.globalId ?? "") ? Theme.of(context).bgColorEF12(context) : Colors.transparent,
                padding: const EdgeInsets.symmetric(vertical: 20),

---------------------------------------------etc

Expected behavior

It happened sometime.

Screenshots

No response

Additional Context

No response

ferrarafer commented 1 year ago

Hi @Kimsoer , I was not able to try your code because we are very busy this week with some work but I think you need to use the AppLifecycleState of the app to do what you want after the app is back on the foreground. Take a look at following article where @FilledStacks explains how to do it.

https://www.filledstacks.com/post/flutter-application-life-cycle-management/

Kimsoer commented 1 year ago

Thank you so much @ferrarafer , I used to try it already like your mention, what my problem is not the cycle because the real time data is trigger and data log is coming what the issue , the state is not re-build the new data trigger from real time rabbit mq

ferrarafer commented 1 year ago

@Kimsoer can you please show the full code of the view and the viewmodel ? Because the code you above is very difficult to read and also I'm seeing things I don't like.

Why are you doing this ?

setBusy(true);
rebuildUi();

When you execute setBusy(true) the view is rebuild.

Kimsoer commented 1 year ago

@ferrarafer this case, i want to have loading, and rebuildUi(), I am not sure , is it wrong way?

Kimsoer commented 1 year ago

View Model


import 'dart:convert';

import 'package:custom_pop_up_menu/custom_pop_up_menu.dart';
import 'package:flutter/material.dart';
import 'package:kds_flutter/core/enums/local_storage.dart';
import 'package:kds_flutter/core/extension/extension.dart';
import 'package:kds_flutter/core/models/requests/order_request.dart';
import 'package:kds_flutter/core/models/responses/group_channel_product_entity.dart';
import 'package:kds_flutter/core/models/responses/group_product_detail_response_entity.dart';
import 'package:kds_flutter/core/models/responses/group_products_response.dart';
import 'package:kds_flutter/core/models/responses/receipt_data_response_entity.dart' as dataPrint;
import 'package:kds_flutter/core/models/responses/table_order_detail_entity.dart';
import 'package:kds_flutter/core/models/responses/table_orders_response_entity.dart';
import 'package:kds_flutter/core/models/responses/table_orders_response_entity.dart' as tblOrder;
import 'package:kds_flutter/core/models/responses/timer_setting_entity.dart';
import 'package:kds_flutter/core/models/responses/verify_pin_code_response_entity.dart';
import 'package:kds_flutter/core/utils/global_function.dart';
import 'package:kds_flutter/services/api_service_provider.dart';
import 'package:kds_flutter/services/local_service.dart';
import 'package:kds_flutter/services/rabbit_mq_service.dart';
import 'package:kds_flutter/services/stomp_client_service.dart';
import 'package:kds_flutter/ui/common/app_colors.dart';
import 'package:kds_flutter/ui/common/app_strings.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:stacked_themes/stacked_themes.dart';

import '../../../app/app.locator.dart';
import '../../../core/models/popup_filter_model.dart';

class HomeViewModel extends BaseViewModel {
  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
  final _dialogService = locator<DialogService>();
  final _navigationService = locator<NavigationService>();
  BuildContext context;
  HomeViewModel(this.context);

  int segmentFilter = 1;
  bool isVisibleSidebar = true;
  bool isVisibleLayout = true;
  bool isVisibleDetailProduct = false;
  bool isMode = true;
  bool isFilterStatus = false;
  bool networkConnection = true;
  bool openInfoConnection = false;

  List<PopupFilterModel> selectedFilter = [];
  bool isEdit = false;
  String? tableOrderGid = "";

  int currentPage = 0;
  CustomPopupMenuController menuController = CustomPopupMenuController();
  String selectGroupProduct = "";

  var verifyPinCodeResponse = VerifyPinCodeResponseEntity();

  var tableOrdersResponse = TableOrdersResponseEntity();
  var groupProductResponse = GroupProductsResponse();

  GroupChannelProductEntity groupChannelProductEntity = GroupChannelProductEntity();

  bool isUpdateStatus = false;
  GroupProductDetailResponseEntity groupProductDetailResponse = GroupProductDetailResponseEntity();
  dataPrint.ReceiptDataResponseEntity receiptDataResponse = dataPrint.ReceiptDataResponseEntity();
  var tableOrderDetail = TableOrderDetailEntity();
  int currentSubIndex = 0;
  int currentIndex = 0;

  var repositoryService = ApiProviderService().getRestClient();
  var filterOpenOrClose = "OPEN";
  var refreshController = RefreshController(initialRefresh: false, initialLoadStatus: LoadStatus.idle);
  var timerSetting = TimerSettingEntity();

  var rabbitMqService = RabbitMqService();
  bool isLogout = false;

  getInstance() async {
    setBusy(false);
    clearErrors();

    getTheme();
    currentPage = 1;

    await getTableOrderData(isRefresh: true);
    await listGroupProductQty();

    var dataResponse = await LocalService().getSavedValue(LocalDataFieldName.pinCodeInfo);
    verifyPinCodeResponse = VerifyPinCodeResponseEntity.fromJson(dataResponse);

    ///Loading data real time
    await getDataRealTimeStomp();

    setInitialised(true);
    rebuildUi();
  }

  /// stomp server
  getDataRealTimeStomp() async {
    await StompClientService(onMessageReceived: (message) async {
      var data = jsonDecode(message);
      if (data["action"] == "kds-newdata" && data["service"] == "UPDATE_GROUP_SUM_PRODUCT") {
        await listGroupProductQty();
      }

      if (data["action"] == "kds-newdata" && data["service"] == "GET_NEW_ORDER") {
        await getTableOrderData();
      }
    }).connectStompServer();

    rebuildUi();
  }

  /// get theme mode
  getTheme() async {
    var mode = getThemeManager(context).selectedThemeMode;
    if (mode == ThemeMode.dark) {
      isMode = false;
    } else {
      isMode = true;
    }
    rebuildUi();
  }

  /// get order list
  bool isRefreshTableOrder = false;
  getTableOrderData({bool? isRefresh}) async {
    try {
      isRefreshTableOrder = isRefresh ?? false;
      rebuildUi();

      if (isRefresh ?? false) {
        setBusyForObject(tableOrdersResponse, true);
        rebuildUi();
      }

      /// set filter to order request
      List<String> filters = [];
      for (var item in selectedFilter) {
        filters.add("${item.value}");
      }

      currentPage = 1;
      OrderRequest orderRequest = OrderRequest(
        perPage: 10,
        currentPage: 1,
        option: filterOpenOrClose,
        filters: filters,
      );

      var response = await ApiProviderService().getRestClient().getOrder(orderRequest);
      if (response.response.statusCode == 200 && response.response.data != null) {
        if (tableOrdersResponse.data?.tableOrders?.isNotEmpty ?? false) {
          tableOrdersResponse.data?.tableOrders?.clear();
        }
        tableOrdersResponse = TableOrdersResponseEntity.fromJson(response.data);
      }
    } catch (error) {
      GlobalFunction.onHttpRequestFail(error, this);
    } finally {
      if (isRefresh ?? false) {
        setBusyForObject(tableOrdersResponse, false);
        rebuildUi();
      }
      isRefreshTableOrder = true;
      rebuildUi();
    }
  }

  /// get list order more
  getTableOrderDataMore() async {
    try {
      if (currentPage < (tableOrdersResponse.data?.meta?.lastPage ?? 0)) {
        currentPage++;

        /// set filter to order request
        List<String> filters = [];
        for (var item in selectedFilter) {
          filters.add("${item.value}");
        }

        OrderRequest orderRequest = OrderRequest(
          perPage: 10,
          currentPage: currentPage,
          option: filterOpenOrClose,
          filters: filters,
        );

        var response = await ApiProviderService().getRestClient().getOrder(orderRequest);
        if (response.response.statusCode == 200) {
          tableOrdersResponse.data?.meta = tblOrder.TableOrdersResponseDataMeta.fromJson(response.response.data['data']['meta']);
          for (var element in (response.response.data['data']['table_orders'] ?? [])) {
            tableOrdersResponse.data?.tableOrders?.add(tblOrder.TableOrdersResponseDataTableOrders.fromJson(element));
          }
        }
      }
    } catch (error) {
      GlobalFunction.onHttpRequestFail(error, this);
    } finally {
      rebuildUi();
      refreshController.loadComplete();
    }
  }

  /// list sidebar group product quantity
  listGroupProductQty() async {
    try {
      setBusyForObject(groupProductResponse, true);
      rebuildUi();

      var response = await ApiProviderService().getRestClient().getGroupProductQty();
      if (response.response.statusCode == 200 && response.response.data != null) {
        groupProductResponse = GroupProductsResponse.fromJson(response.data);
      }
    } catch (error) {
      GlobalFunction.onHttpRequestFail(error, this);
    } finally {
      setBusyForObject(groupProductResponse, false);
      rebuildUi();
    }
  }

  statusColor(String status) {
    var color = color50;
    if (status == pending) {
      color = colorAF;
    } else if (status == reCooking || status == cooking) {
      color = bgColor4D;
    }
    return color;
  }

  statusTextColor(String status) {
    var color = Theme.of(context).color54E0(context);

    if (status == dispatch) {
      color = Theme.of(context).color80A0(context);
    } else if (status == cancelled) {
      color = color6A.withOpacity(0.75);
    }
    return color;
  }

  statusOptionTextColor(String status) {
    var color = Theme.of(context).color54E0(context);

    if (status == dispatch) {
      color = Theme.of(context).color80A0(context);
    } else if (status == cancelled) {
      color = color6A.withOpacity(0.75);
    } else {
      color = colorC7;
    }
    return color;
  }

  bool isClosed(String status) {
    return status == dispatch;
  }
}

View

import 'package:flutter/material.dart';
import 'package:kds_flutter/core/extension/extension.dart';
import 'package:kds_flutter/ui/views/home/home_viewmodel.dart';
import 'package:kds_flutter/ui/views/home/widget/list_layout_widget.dart';
import 'package:kds_flutter/ui/views/home/widget/sidebar_widget.dart';
import 'package:stacked/stacked.dart';

class HomeView extends StatefulWidget {
  const HomeView({Key? key}) : super(key: key);

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  @override
  Widget build(BuildContext context) {
    return ViewModelBuilder<HomeViewModel>.reactive(
        viewModelBuilder: () => HomeViewModel(context),
        disposeViewModel: false,
        onViewModelReady: (viewModel) => viewModel.getInstance(),
        builder: (context, viewModel, child) {
          return Scaffold(
            appBar: AppBar(),
            body: SafeArea(
              child: Stack(
                alignment: Alignment.center,
                children: [
                  Column(
                    children: [
                      /// main contents
                      Expanded(
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            /// side bar
                            Visibility(
                              visible: viewModel.isVisibleSidebar,
                              maintainAnimation: true,
                              maintainState: true,
                              child: const SideBarWidget(),
                            ),

                            /// content
                            Expanded(
                              child: Stack(
                                children: [
                                  /// list layout
                                  if (viewModel.isVisibleLayout && !viewModel.isVisibleDetailProduct)
                                    AnimatedOpacity(
                                      opacity: viewModel.isVisibleLayout ? 1.0 : 0.0,
                                      duration: const Duration(milliseconds: 500),
                                      child: const ListLayoutWidget(),
                                    ),
                                ],
                              ),
                            )
                          ],
                        ),
                      ),
                    ],
                  ),

                  /// loading when logout
                  if (viewModel.isLogout || viewModel.isRefreshTableOrder == false)
                    Container(
                      height: MediaQuery.of(context).size.height,
                      width: MediaQuery.of(context).size.width,
                      color: Theme.of(context).bgColorFF1E(context).withOpacity(0.5),
                      child: Center(
                        child: CircularProgressIndicator.adaptive(
                          valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).primaryColor),
                        ),
                      ),
                    ),
                ],
              ),
            ),
          );
        });
  }
}

Widget View side bar


import 'package:badges/badges.dart' as badges;
import 'package:flutter/material.dart';
import 'package:kds_flutter/core/extension/extension.dart';
import 'package:kds_flutter/ui/common/app_constant.dart';
import 'package:kds_flutter/ui/components/cache_network_image_component.dart';
import 'package:kds_flutter/ui/views/home/home_viewmodel.dart';
import 'package:kds_flutter/ui/views/home/shimmers/sidebar_shimmer.dart';
import 'package:stacked/stacked.dart';

class SideBarWidget extends ViewModelWidget<HomeViewModel> {
  const SideBarWidget({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context, HomeViewModel viewModel) {
    var data = viewModel.groupProductResponse.data?.products;
    return (viewModel.groupProductResponse.data?.products?.isNotEmpty ?? false)
        ? Container(
            width: 120,
            height: MediaQuery.of(context).size.height,
            decoration: BoxDecoration(color: Theme.of(context).bgColorFF1E(context)),
            child: ListView.builder(
              itemCount: data?.length ?? 0,
              shrinkWrap: true,
              padding: const EdgeInsets.all(0),
              itemBuilder: (BuildContext context, int index) {
                var item = data?.elementAt(index);
                return GestureDetector(
                  onTap: () {},
                  child: Container(
                    color: viewModel.selectGroupProduct == (item?.globalId ?? "") ? Theme.of(context).bgColorEF12(context) : Colors.transparent,
                    padding: const EdgeInsets.symmetric(vertical: 20),
                    alignment: Alignment.center,
                    child: badges.Badge(
                      ignorePointer: false,
                      badgeAnimation: const badges.BadgeAnimation.slide(toAnimate: false),
                      position: badges.BadgePosition.topEnd(end: -5, top: -10),
                      badgeContent: Container(
                        width: 28,
                        height: 28,
                        alignment: Alignment.center,
                        child: Text(
                          "${item?.quantity}",
                          style: text14(context).copyWith(
                            color: Colors.white,
                          ),
                          textAlign: TextAlign.center,
                        ),
                      ),
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(80),
                        child: CacheNetworkImageComponent(
                          height: 80,
                          width: 80,
                          radius: 80,
                          boxFix: BoxFit.cover,
                          imageUrl: item?.imageUrl,
                        ),
                      ),
                    ),
                  ),
                );
              },
            ),
          )
        : FutureBuilder(
            builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
              /// loading
              if (snapshot.connectionState == ConnectionState.waiting || viewModel.busy(viewModel.groupProductResponse)) {
                return Container(
                  width: 120,
                  height: MediaQuery.of(context).size.height,
                  decoration: BoxDecoration(color: Theme.of(context).bgColorFF1E(context)),
                  child: const SideBarShimmer(),
                );
              }

              /// empty
              return Container(
                width: 120,
                height: MediaQuery.of(context).size.height,
                decoration: BoxDecoration(color: Theme.of(context).bgColorFF1E(context)),
              );
            },
            future: Future.delayed(const Duration(seconds: 0)),
          );
  }
}

View Widget List


import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:kds_flutter/core/extension/extension.dart';
import 'package:kds_flutter/generated/locale_keys.g.dart';
import 'package:kds_flutter/ui/common/app_colors.dart';
import 'package:kds_flutter/ui/common/app_constant.dart';
import 'package:kds_flutter/ui/common/app_strings.dart';
import 'package:kds_flutter/ui/components/cache_network_image_component.dart';
import 'package:kds_flutter/ui/components/empty_component.dart';
import 'package:kds_flutter/ui/views/home/home_viewmodel.dart';
import 'package:kds_flutter/ui/views/home/shimmers/list_layout_shimmer.dart';
import 'package:kds_flutter/ui/views/home/widget/popup_increase_timer.dart';
import 'package:kds_flutter/ui/views/widget/loading_widget.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:stacked/stacked.dart';

class ListLayoutWidget extends ViewModelWidget<HomeViewModel> {
  const ListLayoutWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, HomeViewModel viewModel) {
    var theme = Theme.of(context);
    var orderLists = viewModel.tableOrdersResponse.data?.tableOrders ?? [];

    if (viewModel.busy(viewModel.tableOrdersResponse)) {
      return const ListLayoutShimmer();
    }
    return SmartRefresher(
      key: viewModel.scaffoldKey,
      physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
      controller: viewModel.refreshController,
      enablePullUp: true,
      scrollDirection: Axis.horizontal,
      onRefresh: () {
        viewModel.getTableOrderData(isRefresh: true);
        viewModel.listGroupProductQty();
        viewModel.refreshController.refreshCompleted();
      },
      header: CustomHeader(
        builder: (BuildContext context, RefreshStatus? mode) {
          return Center(child: Container());
        },
      ),
      footer: CustomFooter(builder: (BuildContext? context, LoadStatus? mode) {
        return Center(child: Container());
      }),
      onLoading: () {
        viewModel.getTableOrderDataMore();
      },
      child: orderLists.isNotEmpty
          ? ListView.separated(
              shrinkWrap: true,
              scrollDirection: Axis.horizontal,
              padding: const EdgeInsets.all(10),
              physics: const BouncingScrollPhysics(),
              itemCount: orderLists.length,
              itemBuilder: (context, index) {
                var data = orderLists.elementAt(index);
                return Container(
                  width: MediaQuery.of(context).size.width / 4,
                  decoration: BoxDecoration(
                    color: theme.bgColorFF1E(context),
                    borderRadius: BorderRadius.circular(10),
                  ),
                  child: Stack(
                    children: [
                      Column(
                        children: [
                          Container(
                            padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                            decoration: BoxDecoration(
                              color: theme.bgColorF927(context),
                              borderRadius: const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)),
                            ),
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Row(
                                  children: [
                                    CacheNetworkImageComponent(
                                      imageUrl: data.imageChannel,
                                      radius: 5,
                                    ),
                                    const SizedBox(width: 8),
                                    Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        Text(
                                          data.tableName ?? '',
                                          style: text12(context).copyWith(fontWeight: FontWeight.w400),
                                        ),
                                        Text(
                                          data.orderNumber ?? '',
                                          style: text14(context).copyWith(color: Theme.of(context).color54E0(context), fontWeight: FontWeight.bold),
                                        ),
                                      ],
                                    ),
                                    const Spacer(),
                                    Column(
                                      crossAxisAlignment: CrossAxisAlignment.end,
                                      mainAxisAlignment: MainAxisAlignment.end,
                                      children: [
                                        if ((data.extraCookingTime ?? 0) > 0 && viewModel.segmentFilter == 1)
                                          Text("+${data.extraCookingTime}min", style: text12(context).copyWith(fontWeight: FontWeight.w600, color: bgColor9A)),
                                      ],
                                    ),
                                    if (viewModel.segmentFilter == 1)
                                      PopupIncreaseTimer(
                                        data: data,
                                        onChanged: (value) {
                                          if (value != "custom") {}
                                        },
                                        state: MyStatePopupIncreaseTimer(),
                                      ),
                                  ],
                                ),
                                const SizedBox(height: 4),
                                Row(
                                  children: [
                                    Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        Text(
                                          LocaleKeys.global_client.tr(),
                                          style: text12(context).copyWith(
                                            color: Theme.of(context).color80A0(context),
                                            fontWeight: FontWeight.w400,
                                            fontSize: 10,
                                          ),
                                        ),
                                        Text(data.clientName?.split(",").first ?? '', style: text14(context)),
                                      ],
                                    ),
                                    const Spacer(),
                                    if ((viewModel.segmentFilter == 2 && data.isPriority == 1) || viewModel.segmentFilter == 1)
                                      GestureDetector(
                                        onTap: viewModel.segmentFilter == 2 ? null : () {},
                                        child: Icon(
                                          Icons.flag,
                                          color: data.isPriority == 1 ? bgColor4D : bgColorB3,
                                        ),
                                      ),
                                    const SizedBox(width: 10),
                                  ],
                                )
                              ],
                            ),
                          ),
                          Expanded(
                            child: ListView.builder(
                              itemCount: data.orderItems?.length ?? 0,
                              physics: const BouncingScrollPhysics(),
                              shrinkWrap: true,
                              addAutomaticKeepAlives: true,
                              itemBuilder: (context, subIndex) {
                                var item = data.orderItems?.elementAt(subIndex);
                                return Padding(
                                  padding: const EdgeInsets.only(top: 6),
                                  child: Column(
                                    crossAxisAlignment: CrossAxisAlignment.center,
                                    mainAxisSize: MainAxisSize.max,
                                    children: [
                                      Row(
                                        crossAxisAlignment: CrossAxisAlignment.start,
                                        mainAxisAlignment: MainAxisAlignment.start,
                                        children: [
                                          Padding(
                                            padding: const EdgeInsets.only(left: 8, right: 10, top: 10),
                                            child: Text(
                                              '${item?.quantity}',
                                              style: text14(context).copyWith(color: viewModel.statusTextColor(item?.status ?? '')),
                                            ),
                                          ),
                                          const SizedBox(width: 8),
                                          Expanded(
                                            child: Container(
                                              padding: const EdgeInsets.only(top: 10),
                                              child: Column(
                                                crossAxisAlignment: CrossAxisAlignment.start,
                                                children: [
                                                  Text(
                                                    item?.productName ?? '',
                                                    style: text14(context).copyWith(color: viewModel.statusTextColor(item?.status ?? ''), fontWeight: FontWeight.w400),
                                                  ),
                                                  if (item?.options?.isNotEmpty ?? false)
                                                    ...List.generate(
                                                      item?.options?.length ?? 0,
                                                      (indexOption) => Row(
                                                        children: [
                                                          const SizedBox(width: 5),
                                                          CircleAvatar(
                                                            radius: 3,
                                                            backgroundColor: viewModel.statusOptionTextColor(item?.status ?? ''),
                                                          ),
                                                          const SizedBox(width: 10),
                                                          Expanded(
                                                            child: Text(
                                                              "${item?.options?.elementAt(indexOption).toString()}",
                                                              style: text14(context).copyWith(color: viewModel.statusOptionTextColor(item?.status ?? '')),
                                                            ),
                                                          ),
                                                        ],
                                                      ),
                                                    ),
                                                ],
                                              ),
                                            ),
                                          ),
                                          Padding(
                                            padding: const EdgeInsets.symmetric(horizontal: 8),
                                            child: viewModel.isClosed(item?.status ?? '')
                                                ? Icon(
                                                    Icons.check,
                                                    size: 24,
                                                    color: theme.bgColorB356(context),
                                                  )
                                                : item?.status == cancelled
                                                    ? Container()
                                                    : TextButton(
                                                        onPressed: () {},
                                                        style: TextButton.styleFrom(backgroundColor: viewModel.statusColor(item?.status ?? '')),
                                                        child: viewModel.busy(viewModel.tableOrderDetail) && subIndex == viewModel.currentSubIndex && viewModel.currentIndex == index
                                                            ? const Padding(
                                                                padding: EdgeInsets.only(right: 9, left: 9),
                                                                child: LoadingWidget(
                                                                  isTreeBounceLoading: true,
                                                                  color: Colors.white,
                                                                ),
                                                              )
                                                            : Text(
                                                                item?.status ?? '',
                                                                style: text14(context).copyWith(color: Colors.white),
                                                              ),
                                                      ),
                                          )
                                        ],
                                      ),
                                      if (item?.status == cancelled && item?.cancelReason != null)
                                        Container(
                                          padding: const EdgeInsets.only(left: 5, top: 5),
                                          alignment: Alignment.centerLeft,
                                          child: Text(
                                            item?.cancelReason ?? '',
                                            style: text14(context).copyWith(color: color6A),
                                            textAlign: TextAlign.right,
                                          ),
                                        ),
                                      if (viewModel.isEdit && viewModel.tableOrderGid == data.mealGid && item?.status == pending)
                                        Align(
                                          alignment: Alignment.centerLeft,
                                          child: TextButton(
                                            onPressed: () {},
                                            child: Text(
                                              LocaleKeys.home_cancel.tr(),
                                              style: text14(context).copyWith(color: Theme.of(context).primaryColor, fontWeight: FontWeight.w500),
                                            ),
                                          ),
                                        ),
                                    ],
                                  ),
                                );
                              },
                            ),
                          ),
                          const SizedBox(height: 60)
                        ],
                      ),
                      Align(
                        alignment: Alignment.bottomCenter,
                        child: Container(
                            padding: const EdgeInsets.all(10),
                            width: MediaQuery.of(context).size.width / 4,
                            decoration: BoxDecoration(
                              color: theme.bgColorF927(context),
                              borderRadius: const BorderRadius.only(bottomRight: Radius.circular(10), bottomLeft: Radius.circular(10)),
                            ),
                            child: viewModel.segmentFilter == 1
                                ? Row(
                                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                    children: [
                                      Expanded(
                                        child: ElevatedButton.icon(
                                          onPressed: () {},
                                          icon: const Icon(Icons.print),
                                          label: Text(LocaleKeys.home_print.tr()),
                                          style: ElevatedButton.styleFrom(backgroundColor: const Color(0xff94BBE9)),
                                        ),
                                      ),
                                      const SizedBox(width: 10),
                                      Expanded(
                                        child: ElevatedButton(
                                          onPressed: () {},
                                          style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFF5CD79A)),
                                          child: Text(LocaleKeys.home_dispatch_all.tr()),
                                        ),
                                      )
                                    ],
                                  )
                                : ElevatedButton.icon(
                                    onPressed: data.isPrintable == 1 //disable printer (data.isPrintable = 0)
                                        ? () {}
                                        : null,
                                    icon: const Icon(Icons.print),
                                    label: Text(LocaleKeys.home_print.tr()),
                                    style: ElevatedButton.styleFrom(backgroundColor: const Color(0xff94BBE9)),
                                  )),
                      ),
                      if (viewModel.isEdit && viewModel.tableOrderGid == data.mealGid && viewModel.segmentFilter == 1)
                        Align(
                          alignment: Alignment.bottomCenter,
                          child: Container(
                            padding: const EdgeInsets.all(10),
                            width: MediaQuery.of(context).size.width / 4.2,
                            decoration: BoxDecoration(
                              color: theme.bgColorF927(context),
                              borderRadius: const BorderRadius.only(bottomRight: Radius.circular(10), bottomLeft: Radius.circular(10)),
                            ),
                            child: ElevatedButton(
                              onPressed: () {},
                              style: ElevatedButton.styleFrom(backgroundColor: Theme.of(context).primaryColor),
                              child: Text(LocaleKeys.home_finish_edit.tr()),
                            ),
                          ),
                        ),
                    ],
                  ),
                );
              },
              separatorBuilder: (context, index) {
                return const SizedBox(width: 10);
              },
            )
          : const Center(
              child: AnimatedOpacity(
                opacity: 1,
                curve: Curves.fastLinearToSlowEaseIn,
                duration: Duration(milliseconds: 1000),
                child: EmptyComponent(),
              ),
            ),
    );
  }
}
FilledStacks commented 1 year ago

Was this reolved?

Kimsoer commented 1 year ago

Still not resloved with Stacked but I try other state management , it working fine, I am not sure why.

FilledStacks commented 1 month ago

Closing this. Please provide an example of the issue and we'll relook at this.