{"id":17238394,"url":"https://github.com/hoc081098/flutter_github_search_rx_redux","last_synced_at":"2026-01-29T21:39:04.004Z","repository":{"id":49368589,"uuid":"291985768","full_name":"hoc081098/flutter_github_search_rx_redux","owner":"hoc081098","description":"🔰 Flutter github search using rx_redux | Functional \u0026 reactive programming with rxdart, rx_redux","archived":false,"fork":false,"pushed_at":"2023-12-15T17:44:37.000Z","size":50195,"stargazers_count":3,"open_issues_count":6,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T08:17:39.554Z","etag":null,"topics":["flutter-bloc","flutter-bloc-pattern","flutter-bloc-pattern-rxdart","flutter-bloc-rxdart","flutter-redux","flutter-redux-demo","flutter-redux-epics","rx-redux","rxdart","rxdart-bloc","rxdart-epic","rxdart-flutter","rxdart-redux","rxredux"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/rx_redux","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoc081098.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-01T12:00:49.000Z","updated_at":"2023-11-26T11:14:25.000Z","dependencies_parsed_at":"2023-12-15T18:52:17.186Z","dependency_job_id":null,"html_url":"https://github.com/hoc081098/flutter_github_search_rx_redux","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/hoc081098/flutter_github_search_rx_redux","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoc081098%2Fflutter_github_search_rx_redux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoc081098%2Fflutter_github_search_rx_redux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoc081098%2Fflutter_github_search_rx_redux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoc081098%2Fflutter_github_search_rx_redux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoc081098","download_url":"https://codeload.github.com/hoc081098/flutter_github_search_rx_redux/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoc081098%2Fflutter_github_search_rx_redux/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259316975,"owners_count":22839532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flutter-bloc","flutter-bloc-pattern","flutter-bloc-pattern-rxdart","flutter-bloc-rxdart","flutter-redux","flutter-redux-demo","flutter-redux-epics","rx-redux","rxdart","rxdart-bloc","rxdart-epic","rxdart-flutter","rxdart-redux","rxredux"],"created_at":"2024-10-15T05:45:31.501Z","updated_at":"2026-01-29T21:39:03.963Z","avatar_url":"https://github.com/hoc081098.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flutter_github_search_rx_redux\n\n-   Flutter github search using [rx_redux](https://pub.dev/packages/rx_redux) \u003cbr\u003e\n-   Functional \u0026 reactive programming with [rxdart](https://pub.dev/packages/rxdart), [rx_redux](https://pub.dev/packages/rx_redux) 🚀\n\n[![Flutter](https://github.com/hoc081098/flutter_github_search_rx_redux/actions/workflows/flutter.yml/badge.svg)](https://github.com/hoc081098/flutter_github_search_rx_redux/actions/workflows/flutter.yml)\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/hoc081098/rx_redux/blob/v2/images/logo.png?raw=true\" alt=\"Logo\" width=\"300\"/\u003e\n\u003c/p\u003e\n\n## Demo\n\n### Android\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://github.com/hoc081098/hoc081098.github.io/blob/master/flutter_github_search_rx_redux/demo.gif?raw=true\" height=\"480\" \u003e \n\u003c/p\u003e\n\n### MacOS desktop\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/hoc081098/flutter_github_search_rx_redux/master/github_search_rxredux.png\" height=\"480\"\u003e\n\u003c/p\u003e\n\n## Effects with RxDart\n\n```dart\nimport 'package:flutter_github_search_rx_redux/domain/search_usecase.dart';\nimport 'package:rx_redux/rx_redux.dart';\nimport 'package:rxdart_ext/rxdart_ext.dart';\n\nimport 'home_action.dart';\nimport 'home_state.dart';\n\nRxReduxStore\u003cHomeAction, HomeState\u003e createStore(SearchUseCase searchUseCase) =\u003e\n    RxReduxStore(\n      initialState: HomeState.initial(),\n      sideEffects: HomeSideEffects(searchUseCase)(),\n      reducer: (state, action) =\u003e action.reduce(state),\n      logger: rxReduxDefaultLogger,\n    );\n\nclass HomeSideEffects {\n  final SearchUseCase _searchUseCase;\n\n  HomeSideEffects(this._searchUseCase);\n\n  List\u003cSideEffect\u003cHomeAction, HomeState\u003e\u003e call() =\u003e [\n        searchActionToTextChangedAction,\n        search,\n        nextPage,\n        retry,\n      ];\n\n  Stream\u003cHomeAction\u003e searchActionToTextChangedAction(\n    Stream\u003cHomeAction\u003e actions,\n    GetState\u003cHomeState\u003e getState,\n  ) =\u003e\n      actions\n          .whereType\u003cSearchAction\u003e()\n          .debounceTime(const Duration(milliseconds: 500))\n          .map((action) =\u003e action.term.trim())\n          .where((term) =\u003e term.isNotEmpty)\n          .distinct()\n          .map((term) =\u003e TextChangedAction((b) =\u003e b..term = term));\n\n  Stream\u003cHomeAction\u003e search(\n    Stream\u003cHomeAction\u003e actions,\n    GetState\u003cHomeState\u003e getState,\n  ) =\u003e\n      actions\n          .whereType\u003cTextChangedAction\u003e()\n          .map((action) =\u003e action.term)\n          .switchMap((term) =\u003e _nextPage(term, 1));\n\n  Stream\u003cHomeAction\u003e nextPage(\n    Stream\u003cHomeAction\u003e actions,\n    GetState\u003cHomeState\u003e getState,\n  ) {\n    final textChangedAction$ = actions.whereType\u003cTextChangedAction\u003e().debug();\n\n    final performLoadingNextPage = (LoadNextPageAction action) {\n      return Stream.value(getState())\n          .where((state) =\u003e state.canLoadNextPage)\n          .exhaustMap((state) =\u003e _nextPage(state.term, state.page + 1)\n              .takeUntil(textChangedAction$)\n              .debug());\n    };\n\n    return actions\n        .whereType\u003cLoadNextPageAction\u003e()\n        .exhaustMap(performLoadingNextPage);\n  }\n\n  Stream\u003cHomeAction\u003e retry(\n    Stream\u003cHomeAction\u003e actions,\n    GetState\u003cHomeState\u003e getState,\n  ) {\n    final textChangedAction$ = actions.whereType\u003cTextChangedAction\u003e().debug();\n\n    final performRetry = (RetryAction action) {\n      return Stream.value(getState())\n          .where((state) =\u003e state.canRetry)\n          .exhaustMap((state) =\u003e _nextPage(state.term, state.page + 1)\n              .takeUntil(textChangedAction$)\n              .debug());\n    };\n\n    return actions.whereType\u003cRetryAction\u003e().exhaustMap(performRetry);\n  }\n\n  Stream\u003cHomeAction\u003e _nextPage(String term, int nextPage) {\n    final loadingAction = SearchLoadingAction((b) =\u003e b\n      ..term = term\n      ..nextPage = nextPage);\n\n    return Rx.fromCallable(() =\u003e _searchUseCase(term: term, page: nextPage))\n        .map\u003cHomeAction\u003e(\n          (items) =\u003e SearchSuccessAction((b) =\u003e b\n            ..term = term\n            ..items.replace(items)),\n        )\n        .startWith(loadingAction)\n        .onErrorReturnWith(\n          (e, s) =\u003e SearchFailureAction((b) =\u003e b\n            ..error = e\n            ..term = term),\n        );\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoc081098%2Fflutter_github_search_rx_redux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoc081098%2Fflutter_github_search_rx_redux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoc081098%2Fflutter_github_search_rx_redux/lists"}