{"id":18264742,"url":"https://github.com/reactcomponentkit/helloroom","last_synced_at":"2026-04-19T13:32:41.886Z","repository":{"id":137750981,"uuid":"192548504","full_name":"ReactComponentKit/HelloRoom","owner":"ReactComponentKit","description":"Basic Android Room Database Example with Android ReactComponentKit.","archived":false,"fork":false,"pushed_at":"2019-08-31T14:36:03.000Z","size":414,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-09T01:41:59.923Z","etag":null,"topics":["android","component","mvvm","react","redux","room","room-database"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ReactComponentKit.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":"2019-06-18T13:44:41.000Z","updated_at":"2019-08-31T14:36:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"b7c9bad9-989f-4947-a7cb-b1d2ac29cb99","html_url":"https://github.com/ReactComponentKit/HelloRoom","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ReactComponentKit/HelloRoom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FHelloRoom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FHelloRoom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FHelloRoom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FHelloRoom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ReactComponentKit","download_url":"https://codeload.github.com/ReactComponentKit/HelloRoom/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FHelloRoom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32009130,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["android","component","mvvm","react","redux","room","room-database"],"created_at":"2024-11-05T11:15:47.572Z","updated_at":"2026-04-19T13:32:41.571Z","avatar_url":"https://github.com/ReactComponentKit.png","language":"Kotlin","readme":"# HelloRoom\n\nBasic Android Room Database Example with Android ReactComponentKit.\n\n![](./art/result.gif)\n\n## Actions\n\n```kotlin\n// Load all words from the DB\nobject LoadWordsAction: Action\n\n// Insert an word into the DB\ndata class InsertWordAction(val word: Word): Action\n\n// Delete an word in the DB\ndata class DeleteWordAction(val word: Word): Action\n```\n\n## Reducers\n\n```kotlin\n// Load all words from the DB\nfun MainViewModel.loadWords(state: MainViewState): MainViewState {\n\n    val words = WordDB.getInstance(getApplication())\n        .wordDao()\n        .getAlphabetizedWords()\n\n    return state.copy(words = words)\n}\n\n// Insert an word into the DB\nfun MainViewModel.insertWord(state: MainViewState, action: InsertWordAction): MainViewState {\n\n    WordDB.getInstance(getApplication())\n        .wordDao()\n        .insert(action.word)\n\n    return state\n}\n\n// Delete an word in the DB\nfun MainViewModel.deleteWord(state: MainViewState, action: DeleteWordAction): MainViewState {\n\n    WordDB.getInstance(getApplication())\n        .wordDao()\n        .delete(action.word)\n\n    return state\n}\n```\n\n## Make Item models for RecyclerView\n\n```kotlin\n// Make ItemModels from word list for the recycler view\nfun MainViewModel.makeItemModels(state: MainViewState): MainViewState {\n\n    val itemModels = state.words.map { WordModel(it) }\n\n    return state.copy(itemModels = itemModels)\n}\n```\n\n## State\n\n```kotlin\ndata class MainViewState(\n    val words: List\u003cWord\u003e = emptyList(),\n    val itemModels: List\u003cWordModel\u003e = emptyList()\n): State() {\n    override fun copyState(): MainViewState {\n        return copy()\n    }\n}\n```\n\n## MainViewModel\n\n```kotlin\nclass MainViewModel(application: Application): RCKViewModel\u003cMainViewState\u003e(application) {\n\n    val itemModels = Output\u003cList\u003cWordModel\u003e\u003e(emptyList())\n\n    override fun setupStore() {\n\n        initStore { store -\u003e\n            store.initialState(MainViewState())\n\n            store.flow\u003cLoadWordsAction\u003e(\n                { state, _ -\u003e loadWords(state) },\n                { state, _ -\u003e makeItemModels(state) }\n            )\n\n            store.flow\u003cInsertWordAction\u003e(\n                ::insertWord,\n                { state, _ -\u003e loadWords(state) },\n                { state, _ -\u003e makeItemModels(state) }\n            )\n\n            store.flow\u003cDeleteWordAction\u003e(\n                ::deleteWord,\n                { state, _ -\u003e loadWords(state) },\n                { state, _ -\u003e makeItemModels(state) }\n            )\n        }\n    }\n\n    operator fun get(index: Int): Word = withState { state -\u003e\n        state.words[index]\n    }\n\n    override fun on(newState: MainViewState) {\n        itemModels.accept(newState.itemModels)\n    }\n\n    override fun on(error: Error) {\n        Log.e(\"MainViewModel\", error.toString())\n    }\n}\n```\n\n## MainActivity\n\n```kotlin\nclass MainActivity : AppCompatActivity() {\n\n    private lateinit var viewModel: MainViewModel\n    private val disposeBag: AutoDisposeBag by lazy {\n        AutoDisposeBag(this)\n    }\n\n    private val layoutManager: LinearLayoutManager by lazy {\n        LinearLayoutManager(this, RecyclerView.VERTICAL, false)\n    }\n\n    private val adapter: RecyclerViewAdapter by lazy {\n        RecyclerViewAdapter(token = viewModel.token, useDiff = true)\n    }\n\n    private val itemTouchHelper: ItemTouchHelper by lazy {\n        ItemTouchHelper(SwipeToDeleteCallback {\n            val word = viewModel[it]\n            viewModel.dispatch(DeleteWordAction(word))\n        })\n    }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n        setSupportActionBar(toolbar)\n\n        viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)\n\n        adapter.register(WordComponent::class)\n        recyclerview.layoutManager = layoutManager\n        recyclerview.adapter = adapter\n        itemTouchHelper.attachToRecyclerView(recyclerview)\n\n        loadWords()\n        handleClickEvents()\n        handleViewModelOutputs()\n    }\n\n    private fun loadWords() {\n        viewModel.dispatch(LoadWordsAction)\n    }\n\n    private fun handleClickEvents() {\n        fab.onClick {\n            val word = Word(WordUtils.randomWord)\n            viewModel.dispatch(InsertWordAction(word))\n        }\n    }\n\n    private fun handleViewModelOutputs() {\n        viewModel\n            .itemModels\n            .asObservable()\n            .subscribe {\n                adapter.set(it)\n            }\n            .disposedBy(disposeBag)\n    }\n}\n```\n\n## MIT License\n\nThe MIT License (MIT)\n\nCopyright (c) 2019 Sungcheol Kim, [https://github.com/ReactComponentKit/HelloRoom](https://github.com/ReactComponentKit/HelloRoom)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactcomponentkit%2Fhelloroom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freactcomponentkit%2Fhelloroom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactcomponentkit%2Fhelloroom/lists"}