├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── Bug.md │ ├── Docs.md │ ├── Feature.md │ └── Refactor.md ├── pull_request_template.md └── workflows │ └── android-pull-request-ci.yml ├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── sopt │ │ └── linkmind │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── linkmind │ │ │ ├── LinkMindApp.kt │ │ │ ├── SplashActivity.kt │ │ │ └── configuration │ │ │ └── ToasterMessagingService.kt │ └── res │ │ ├── drawable │ │ └── ic_launcher_foreground.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ └── values │ │ └── ic_launcher_background.xml │ └── test │ └── java │ └── org │ └── sopt │ └── linkmind │ └── ExampleUnitTest.kt ├── build-logic ├── convention │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ ├── AndroidApplicationConventionPlugin.kt │ │ ├── AndroidHiltConventionPlugin.kt │ │ ├── AndroidLibraryConventionPlugin.kt │ │ ├── DataModuleConventionPlugin.kt │ │ ├── FeatureConventionPlugin.kt │ │ ├── JavaLibraryConventionPlugin.kt │ │ └── com │ │ └── linkmind │ │ └── convention │ │ ├── Const.kt │ │ ├── KotlinAndroid.kt │ │ └── ProjectExt.kt └── settings.gradle.kts ├── build.gradle.kts ├── core ├── auth │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── auth │ │ ├── model │ │ ├── Auth.kt │ │ ├── Token.kt │ │ └── UserData.kt │ │ └── repository │ │ └── AuthRepository.kt ├── authimpl │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── authimpl │ │ ├── di │ │ ├── ApiModule.kt │ │ ├── DataSourceModule.kt │ │ └── RepositoryModule.kt │ │ ├── model │ │ ├── request │ │ │ └── RequestPostAuthDto.kt │ │ └── response │ │ │ ├── ResponsePostAuthDto.kt │ │ │ └── ResponsePostSignOutDto.kt │ │ ├── repository │ │ └── AuthRepositoryImpl.kt │ │ ├── source │ │ ├── local │ │ │ └── AuthLocalDataSource.kt │ │ └── remote │ │ │ └── AuthRemoteDataSource.kt │ │ └── sourceimpl │ │ ├── local │ │ └── AuthLocalDataSourceImpl.kt │ │ └── remote │ │ ├── AuthRemoteDataSourceImpl.kt │ │ └── api │ │ └── AuthService.kt ├── common │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── common │ │ ├── intentprovider │ │ ├── IntentProvider.kt │ │ └── Qualifier.kt │ │ └── util │ │ ├── Sample.kt │ │ ├── StringExt.kt │ │ └── throttleValue │ │ └── ThrottleValue.kt ├── datastore │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── datastore │ │ ├── datastore │ │ └── SecurityDataStore.kt │ │ └── di │ │ └── DataStoreModule.kt ├── designsystem │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── designsystem │ │ │ └── components │ │ │ ├── bottomsheet │ │ │ ├── BottomSheetType.kt │ │ │ └── LinkMindBottomSheet.kt │ │ │ ├── button │ │ │ ├── LinkMindBlockButton.kt │ │ │ ├── LinkMindFullWidthButton.kt │ │ │ ├── LinkMindPopUpButton.kt │ │ │ └── state │ │ │ │ ├── LinkMIndFullWidthButtonState.kt │ │ │ │ └── LinkMindButtonState.kt │ │ │ ├── dialog │ │ │ └── LinkMindDialog.kt │ │ │ ├── edittext │ │ │ ├── LinkMindEditTextBox.kt │ │ │ ├── LinkMindEditTextSearch.kt │ │ │ └── state │ │ │ │ └── LinkMindEditTextState.kt │ │ │ ├── horizontalprogressbar │ │ │ └── LinkMindHorizontalProgressBar.kt │ │ │ ├── toast │ │ │ └── LinkMindSnackBar.kt │ │ │ └── toggle │ │ │ └── ToasterToggle.kt │ │ └── res │ │ ├── anim │ │ ├── from_bottom.xml │ │ ├── from_left.xml │ │ ├── from_right.xml │ │ ├── to_bottom.xml │ │ ├── to_left.xml │ │ └── to_right.xml │ │ ├── drawable │ │ ├── ic_alarm_24.xml │ │ ├── ic_alarm_disabled_20.xml │ │ ├── ic_alert_18_white.xml │ │ ├── ic_all_clip_menu.xml │ │ ├── ic_arrow_18_svg.xml │ │ ├── ic_arrow_20.xml │ │ ├── ic_arrow_black_svg.xml │ │ ├── ic_arrow_left_24.xml │ │ ├── ic_cancle_24.xml │ │ ├── ic_check_18_primary.xml │ │ ├── ic_check_18_white.xml │ │ ├── ic_clip_24.xml │ │ ├── ic_clip_24_primary.xml │ │ ├── ic_clip_all_24.xml │ │ ├── ic_clip_all_24_primary.xml │ │ ├── ic_clip_unclicked.xml │ │ ├── ic_close_20.xml │ │ ├── ic_close_24.xml │ │ ├── ic_edit_24.xml │ │ ├── ic_ellipse_18.xml │ │ ├── ic_ellipse_99.xml │ │ ├── ic_gnb_back_24.xml │ │ ├── ic_home1_24.xml │ │ ├── ic_home1_unclicked.xml │ │ ├── ic_home_24.xml │ │ ├── ic_home_clip_20.xml │ │ ├── ic_home_unclicked.xml │ │ ├── ic_internet_after_24.xml │ │ ├── ic_kakaologin_24.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_meatballs_24.xml │ │ ├── ic_minus_28.xml │ │ ├── ic_more_24.xml │ │ ├── ic_my_24.xml │ │ ├── ic_my_select_24.xml │ │ ├── ic_my_unclicked.xml │ │ ├── ic_my_unselectd_24.xml │ │ ├── ic_pin_24.xml │ │ ├── ic_plus_18_orange.xml │ │ ├── ic_plus_24.xml │ │ ├── ic_plus_white_24.xml │ │ ├── ic_read.xml │ │ ├── ic_read_after_24.xml │ │ ├── ic_read_check.xml │ │ ├── ic_reload_24.xml │ │ ├── ic_search_20.xml │ │ ├── ic_search_24.xml │ │ ├── ic_search_24_unselected.xml │ │ ├── ic_setting_24.xml │ │ ├── ic_share.xml │ │ ├── ic_timer_24.xml │ │ ├── ic_timer_unclicked.xml │ │ ├── ic_toggle_ellipse_18.xml │ │ ├── ic_toggle_off_background.xml │ │ ├── ic_toggle_on_background.xml │ │ ├── ic_webview_before_read.xml │ │ ├── img_clip_empty.png │ │ ├── img_link_empty.png │ │ ├── img_link_thumb.png │ │ ├── img_login.png │ │ ├── img_mypage_alarm.png │ │ ├── img_mypage_profile.png │ │ ├── img_notification_permission.png │ │ ├── img_onboarding_first.png │ │ ├── img_onboarding_second.png │ │ ├── img_onboarding_third.png │ │ ├── img_search_none_result.png │ │ ├── img_timer_none.png │ │ ├── img_toast.jpg │ │ ├── img_toaster.png │ │ ├── img_toaster_title.png │ │ ├── progress_bar_horizontal.xml │ │ ├── ripple_btn.xml │ │ ├── sel_bnv_clip.xml │ │ ├── sel_bnv_home.xml │ │ ├── sel_bnv_my.xml │ │ ├── sel_bnv_search.xml │ │ ├── sel_bnv_text_color.xml │ │ ├── sel_bnv_timer.xml │ │ ├── shape_gray_fill_12_rect.xml │ │ ├── shape_grey900_fill_8_rect.xml │ │ ├── shape_kakao_fill_12_rect.xml │ │ ├── shape_neutrals050_fill_12_rect.xml │ │ ├── shape_neutrals050_line_12_rect.xml │ │ ├── shape_neutrals100_fill_12_rect.xml │ │ ├── shape_neutrals100_line_line.xml │ │ ├── shape_neutrals200_fill_12_rect.xml │ │ ├── shape_neutrals850_fill_12_rect.xml │ │ ├── shape_neutrals_fill_12_rect.xml │ │ ├── shape_neutrals_fill_8_rect.xml │ │ ├── shape_neutrals_fill_error_line_12_rect.xml │ │ ├── shape_neutrals_fill_top20_rect.xml │ │ ├── shape_primary_fill_4_rect.xml │ │ ├── shape_primary_fill_8_rect.xml │ │ ├── shape_red_fill_8_rect.xml │ │ ├── shape_white_fill_12_rect.xml │ │ ├── shape_white_fill_2_rect.xml │ │ ├── tool_tip.xml │ │ ├── tooltip_copy.xml │ │ ├── tooltip_move_clip.xml │ │ ├── tooltip_open.xml │ │ └── tooltip_search.xml │ │ ├── font │ │ ├── font_suit_bold.xml │ │ ├── font_suit_extrabold.xml │ │ ├── font_suit_medium.xml │ │ ├── font_suit_regular.xml │ │ ├── font_suit_semibold.xml │ │ ├── suit_bold.otf │ │ ├── suit_extrabold.otf │ │ ├── suit_medium.otf │ │ ├── suit_regular.otf │ │ └── suit_semibold.otf │ │ ├── layout │ │ ├── bottom_sheet_dialog_linkmind.xml │ │ ├── button_block_linkmind.xml │ │ ├── button_full_width_linkmind.xml │ │ ├── button_pop_up_linkmind.xml │ │ ├── dialog_linkmind.xml │ │ ├── edit_text_box_linkmind.xml │ │ ├── edit_text_search_box_linkmind.xml │ │ ├── layout_toaster_snackbar.xml │ │ ├── progress_bar_linkmind.xml │ │ └── toggle_linkmind.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values-night │ │ └── themes.xml │ │ ├── values-v31 │ │ └── themes.xml │ │ ├── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ ├── themes.xml │ │ └── typography.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ ├── data_extraction_rules.xml │ │ └── toggle_motion_scene.xml ├── model │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── model │ │ ├── category │ │ ├── Category.kt │ │ ├── CategoryChangePriority.kt │ │ ├── CategoryDuplicate.kt │ │ ├── CategoryLink.kt │ │ ├── CategoryLinkList.kt │ │ ├── CategoryList.kt │ │ ├── SearchResultList.kt │ │ └── Toast.kt │ │ ├── home │ │ ├── MainPageData.kt │ │ ├── PopupInfo.kt │ │ ├── PopupInvisible.kt │ │ ├── RecentSavedLink.kt │ │ ├── RecommendLink.kt │ │ └── WeekBestLink.kt │ │ ├── timer │ │ ├── Clip.kt │ │ ├── Repeat.kt │ │ ├── Timer.kt │ │ └── TimerData.kt │ │ └── user │ │ ├── MyPageData.kt │ │ └── SettingPageData.kt ├── network │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── network │ │ ├── authenticator │ │ └── LinkMindAuthenticator.kt │ │ ├── di │ │ ├── ApiModule.kt │ │ ├── NetworkModule.kt │ │ └── Qualifier.kt │ │ ├── interceptor │ │ └── AuthenticationIntercept.kt │ │ ├── model │ │ └── response │ │ │ ├── ResponsePostAuthRefreshDto.kt │ │ │ └── base │ │ │ └── BaseResponse.kt │ │ └── service │ │ └── TokenRefreshService.kt └── ui │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── sopt │ └── ui │ ├── base │ ├── BindingActivity.kt │ ├── BindingBottomSheetDialogFragment.kt │ ├── BindingDialogFragment.kt │ └── BindingFragment.kt │ ├── context │ └── ContextExt.kt │ ├── fragment │ └── FragmentExt.kt │ ├── intent │ └── IntentExt.kt │ ├── keyboard │ └── KeyboardUtils.kt │ ├── nav │ └── DeepLinkUtil.kt │ └── view │ ├── CaculateMarignDialog.kt │ ├── ItemDiffCallback.kt │ ├── ThrottleClickListner.kt │ └── UiState.kt ├── data-local └── linkminddata-local │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── sopt │ └── linkminddatalocal │ ├── di │ └── DataSourceModule.kt │ └── source │ └── DummyLocalDataSourceImpl.kt ├── data-remote ├── category │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── dataremote │ │ └── category │ │ ├── api │ │ ├── CategoryService.kt │ │ └── SearchService.kt │ │ ├── datasource │ │ ├── RemoteCategoryDataSourceImpl.kt │ │ └── RemoteSearchDataSourceImpl.kt │ │ ├── di │ │ ├── CategoryDataSourceModule.kt │ │ ├── CategoryServiceModule.kt │ │ ├── SearchDataSourceModule.kt │ │ └── SearchServiceModule.kt │ │ ├── request │ │ ├── RequestCategoryDeleteDTO.kt │ │ ├── RequestCategoryDuplicateDTO.kt │ │ ├── RequestCategoryEditTitleDTO.kt │ │ ├── RequestCategoryPriorityDTO.kt │ │ ├── RequestCategoryTitleDto.kt │ │ └── RequestSearchDto.kt │ │ └── response │ │ ├── ResponseCategoryDuplicateDTO.kt │ │ ├── ResponseCategoryEntireDto.kt │ │ ├── ResponseLinksDTO.kt │ │ └── ResponseSearchDto.kt ├── home │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── remote │ │ └── home │ │ ├── api │ │ ├── HomeService.kt │ │ └── PopupService.kt │ │ ├── datasource │ │ ├── RemoteHomeDataSourceImpl.kt │ │ └── RemotePopupDatasourceImpl.kt │ │ ├── di │ │ ├── HomeDataSourceModule.kt │ │ └── HomeServiceModule.kt │ │ ├── request │ │ └── RequestPopupInvisibleDto.kt │ │ └── response │ │ ├── ResponseMainPageDto.kt │ │ ├── ResponsePopupInfoDto.kt │ │ ├── ResponsePopupInvisibleDto.kt │ │ ├── ResponseRecentSavedLinkDto.kt │ │ ├── ResponseRecommendLinkDto.kt │ │ └── ResponseWeekBestLinkDto.kt ├── link │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── remote │ │ └── link │ │ ├── api │ │ └── LinkService.kt │ │ ├── datasource │ │ └── RemoteLinkDataSourceImpl.kt │ │ ├── di │ │ ├── LinkDataSourceModule.kt │ │ └── LinkServiceModule.kt │ │ ├── request │ │ ├── RequestIsReadDto.kt │ │ ├── RequestPatchCategoryDto.kt │ │ ├── RequestPatchTitleDto.kt │ │ └── RequestWriteDto.kt │ │ └── response │ │ ├── ResponseIsReadDto.kt │ │ ├── ResponsePatchCategoryDto.kt │ │ └── ResponsePatchTitleDto.kt ├── timer │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── timerremote │ │ ├── api │ │ └── TimerService.kt │ │ ├── di │ │ ├── ApiModule.kt │ │ └── DataSourceModule.kt │ │ ├── model │ │ ├── request │ │ │ ├── RequestPatchTimerDto.kt │ │ │ └── RequestPostTimerDto.kt │ │ └── response │ │ │ ├── ResponseGetTimerDto.kt │ │ │ └── ResponseGetTimerPageDto.kt │ │ └── source │ │ └── TimerRemoteDataSourceImpl.kt └── user │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ ├── api │ └── UserService.kt │ ├── datasource │ └── RemoteUserDataSourceImpl.kt │ ├── di │ ├── UserDataSourceModule.kt │ └── UserServiceModule.kt │ ├── request │ └── RequestIsAllowedDto.kt │ └── response │ ├── ResponseGetUserMyPageDto.kt │ ├── ResponseGetUserSettingDto.kt │ └── ResponseIsAllowedDto.kt ├── data ├── category │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── data │ │ └── category │ │ ├── datasource │ │ ├── RemoteCategoryDataSource.kt │ │ └── RemoteSearchDataSource.kt │ │ ├── di │ │ └── RepositoryModule.kt │ │ └── repository │ │ ├── CategoryRepoImpl.kt │ │ └── SearchRepoImpl.kt ├── home │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── home │ │ ├── datasource │ │ ├── RemoteHomeDataSource.kt │ │ └── RemotePopupDataSource.kt │ │ ├── di │ │ └── RepositoryModule.kt │ │ └── repository │ │ ├── HomeRepoImpl.kt │ │ └── PopupRepoImpl.kt ├── link │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── data │ │ └── link │ │ ├── datasource │ │ └── RemoteLinkDataSource.kt │ │ ├── di │ │ └── RepositoryModule.kt │ │ └── repository │ │ └── LinkRepoImpl.kt ├── oauthdata │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── oauthdata │ │ ├── di │ │ ├── ClientModule.kt │ │ └── KakaoAuthModule.kt │ │ └── interactor │ │ └── KakaoAuthInteractor.kt ├── timer │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── timer │ │ ├── di │ │ └── RepositoryModule.kt │ │ ├── repository │ │ └── TimerRepositoryImpl.kt │ │ └── source │ │ ├── local │ │ └── TimerLocalDataSource.kt │ │ └── remote │ │ └── TimerRemoteDataSource.kt └── user │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── sopt │ └── user │ ├── di │ └── RepositoryModule.kt │ ├── repository │ └── UserRepositoryImpl.kt │ └── source │ └── RemoteUserDataSource.kt ├── detekt-config.yml ├── domain ├── category │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── domain │ │ └── category │ │ └── category │ │ ├── repository │ │ ├── CategoryRepository.kt │ │ └── SearchRepository.kt │ │ └── usecase │ │ ├── DeleteCategoryUseCase.kt │ │ ├── GetCategoryAllUseCase.kt │ │ ├── GetCategoryDuplicateUseCase.kt │ │ ├── GetCategoryLinkUseCase.kt │ │ ├── GetSearchResultUserCase.kt │ │ ├── PatchCategoryEditPriorityUseCase.kt │ │ ├── PatchCategoryEditTitleUseCase.kt │ │ └── PostAddCategoryTitleUseCase.kt ├── home │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── sopt │ │ └── home │ │ ├── repository │ │ ├── HomeRepository.kt │ │ └── PopupRepository.kt │ │ └── usecase │ │ ├── GetMainPageUserClip.kt │ │ ├── GetPopupInfo.kt │ │ ├── GetRecentSavedLink.kt │ │ ├── GetRecommendSite.kt │ │ ├── GetWeekBestLink.kt │ │ └── PatchPopupInvisible.kt ├── link │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── sopt │ │ └── domain │ │ └── link │ │ ├── repository │ │ └── LinkRepository.kt │ │ └── usecase │ │ ├── DeleteLinkUseCase.kt │ │ ├── PatchLinkCategoryUseCase.kt │ │ ├── PatchLinkTitleUseCase.kt │ │ ├── PatchReadLinkUseCase.kt │ │ └── PostSaveLinkUseCase.kt ├── oauthdomain │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── sopt │ │ └── oauthdomain │ │ ├── entity │ │ └── KakaoToken.kt │ │ └── interactor │ │ └── OAuthInteractor.kt ├── timer │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── sopt │ │ └── timer │ │ ├── repository │ │ └── TimerRepository.kt │ │ └── usecase │ │ ├── DeleteTimerUseCase.kt │ │ ├── FormatRepeatListToIntList.kt │ │ ├── FormatRepeatListToStringList.kt │ │ ├── GetTimerMainUseCase.kt │ │ ├── PatchAlarmUseCase.kt │ │ ├── PatchTimerUseCase.kt │ │ └── PostTimerUseCase.kt └── user │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── sopt │ └── user │ ├── repository │ └── UserRepository.kt │ └── usecase │ ├── GetUserMyPageUseCase.kt │ ├── GetUserSettingUseCase.kt │ └── PatchPushUseCase.kt ├── feature ├── clip │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── clip │ │ │ ├── DeleteLinkBottomSheetFragment.kt │ │ │ ├── SelectedToggle.kt │ │ │ ├── clip │ │ │ ├── ClipAdapter.kt │ │ │ ├── ClipFragment.kt │ │ │ ├── ClipViewHolder.kt │ │ │ └── ClipViewModel.kt │ │ │ ├── clipchange │ │ │ ├── ClipChangeAdapter.kt │ │ │ ├── ClipChangeFragment.kt │ │ │ └── ClipChangeViewHolder.kt │ │ │ ├── clipedit │ │ │ ├── ClipEditAdapter.kt │ │ │ ├── ClipEditFragment.kt │ │ │ ├── ClipEditViewHolder.kt │ │ │ ├── ClipEditViewModel.kt │ │ │ └── ItemTouchCallback.kt │ │ │ ├── cliplink │ │ │ ├── ClipLinkAdapter.kt │ │ │ ├── ClipLinkFragment.kt │ │ │ ├── ClipLinkViewHolder.kt │ │ │ └── ClipLinkViewModel.kt │ │ │ └── webview │ │ │ ├── WebViewFragment.kt │ │ │ └── WebViewViewModel.kt │ │ └── res │ │ ├── drawable │ │ ├── ic_back_24.xml │ │ ├── ic_next_24.xml │ │ ├── ic_read_before_24.xml │ │ ├── shape_grey050_fill_12_rect.xml │ │ ├── shape_grey050_fill_8_rect.xml │ │ ├── shape_parent_fill_rect.xml │ │ ├── shape_white_fill_12_rect.xml │ │ └── shape_white_fill_8_rect.xml │ │ ├── layout │ │ ├── fragment_clip.xml │ │ ├── fragment_clip_change.xml │ │ ├── fragment_clip_edit.xml │ │ ├── fragment_clip_link.xml │ │ ├── fragment_delete_link_bottom_sheet.xml │ │ ├── fragment_webview.xml │ │ ├── item_clip_change.xml │ │ ├── item_clip_clip.xml │ │ ├── item_clip_edit_clip.xml │ │ ├── item_clip_link.xml │ │ └── item_search_result_clip_link.xml │ │ ├── navigation │ │ └── nav_graph_clip.xml │ │ └── xml │ │ └── filter_motion_scene.xml ├── home │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── home │ │ │ ├── HomeContract.kt │ │ │ ├── HomeFragment.kt │ │ │ ├── HomeViewModel.kt │ │ │ ├── MarketUpdateDialogFragment.kt │ │ │ ├── SurveyDialogFragment.kt │ │ │ ├── adapter │ │ │ ├── HomeClipAdapter.kt │ │ │ ├── HomeWeekLinkAdapter.kt │ │ │ ├── HomeWeekRecommendLinkAdapter.kt │ │ │ └── ItemDecoration.kt │ │ │ ├── model │ │ │ └── UpdatePriority.kt │ │ │ └── viewholder │ │ │ ├── HomeClipViewHolder.kt │ │ │ ├── HomeWeekLinkViewHolder.kt │ │ │ └── HomeWeekRecommendLinkViewHolder.kt │ │ └── res │ │ ├── drawable │ │ └── shape_test.xml │ │ ├── layout │ │ ├── fragment_home.xml │ │ ├── fragment_market_update_dialog.xml │ │ ├── fragment_survey_dialog.xml │ │ ├── item_home_clip.xml │ │ ├── item_week_link.xml │ │ └── item_week_recommend_link.xml │ │ ├── navigation │ │ └── nav_graph_home.xml │ │ └── values │ │ └── dimen.xml ├── login │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── login │ │ │ └── onboarding │ │ │ ├── LoginActivity.kt │ │ │ ├── LoginViewModel.kt │ │ │ ├── LoginViewPagerAdapter.kt │ │ │ ├── di │ │ │ └── IntentModule.kt │ │ │ └── intentprovider │ │ │ └── IntentProviderImpl.kt │ │ └── res │ │ └── layout │ │ ├── activity_login.xml │ │ ├── item_onboarding_first.xml │ │ ├── item_onboarding_fourth.xml │ │ ├── item_onboarding_second.xml │ │ └── item_onboarding_third.xml ├── maincontainer │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── maincontainer │ │ │ ├── MainActivity.kt │ │ │ ├── MainContract.kt │ │ │ ├── MainViewModel.kt │ │ │ ├── di │ │ │ └── IntentModule.kt │ │ │ └── intentprovider │ │ │ └── IntentProviderImpl.kt │ │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── menu │ │ ├── main_nav_menu.xml │ │ └── menu_clip_tb.xml │ │ └── navigation │ │ └── nav_graph.xml ├── mypage │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── mypage │ │ │ ├── my │ │ │ ├── MyFragment.kt │ │ │ └── MyPageViewModel.kt │ │ │ └── settings │ │ │ ├── SettingsFragment.kt │ │ │ └── SettingsViewModel.kt │ │ └── res │ │ ├── layout │ │ ├── fragment_my.xml │ │ └── fragment_settings.xml │ │ └── navigation │ │ └── nav_graph_mypage.xml ├── savelink │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── savelink │ │ │ └── ui │ │ │ ├── adapter │ │ │ └── ClipSelectAdapter.kt │ │ │ ├── model │ │ │ └── Clip.kt │ │ │ ├── savelink │ │ │ ├── LinkContract.kt │ │ │ ├── SaveLinkFragment.kt │ │ │ └── SaveLinkViewModel.kt │ │ │ ├── savelinksetclip │ │ │ ├── SaveLinkSetClipFragment.kt │ │ │ ├── SetLinkContract.kt │ │ │ └── SetLinkViewModel.kt │ │ │ └── viewholder │ │ │ └── ClipSelectViewHolder.kt │ │ └── res │ │ ├── layout │ │ ├── fragment_save_link.xml │ │ ├── fragment_save_link_set_clip.xml │ │ ├── fragment_timer_clip_select.xml │ │ └── item_timer_clip_select.xml │ │ └── navigation │ │ └── nav_graph_save_link.xml ├── search │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── search │ │ │ ├── SearchContract.kt │ │ │ ├── SearchFragment.kt │ │ │ ├── SearchViewModel.kt │ │ │ ├── adapter │ │ │ ├── ClipResultAdapter.kt │ │ │ └── LinkResultAdapter.kt │ │ │ ├── util │ │ │ └── TextStylerExt.kt │ │ │ └── viewholder │ │ │ ├── ClipResultViewHolder.kt │ │ │ └── LinkResultViewHolder.kt │ │ └── res │ │ ├── layout │ │ ├── fragment_search.xml │ │ ├── item_search_link.xml │ │ └── item_search_result_clip.xml │ │ └── navigation │ │ └── nav_graph_search.xml ├── share │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── org │ │ │ └── sopt │ │ │ └── share │ │ │ ├── ShareActivity.kt │ │ │ ├── ShareBottomSheetFragment.kt │ │ │ ├── ShareContract.kt │ │ │ ├── ShareViewModel.kt │ │ │ ├── adapter │ │ │ └── ClipSelectAdapter.kt │ │ │ ├── model │ │ │ └── Clip.kt │ │ │ └── viewholder │ │ │ └── ClipSelectViewHolder.kt │ │ └── res │ │ └── layout │ │ ├── activity_share.xml │ │ ├── fragment_share_bottom_sheet.xml │ │ └── item_timer_clip_select.xml └── timer │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── sopt │ │ └── timer │ │ ├── CompleteTimerAdapter.kt │ │ ├── CompleteTimerViewHolder.kt │ │ ├── NotificationPermissionDialogFragment.kt │ │ ├── TimerFragment.kt │ │ ├── TimerViewModel.kt │ │ ├── WaitTimerAdapter.kt │ │ ├── WaitTimerViewHolder.kt │ │ ├── model │ │ ├── PickerItem.kt │ │ ├── TimePicker.kt │ │ └── Timer.kt │ │ ├── modifytimer │ │ └── ModifyTimerBottomSheetFragment.kt │ │ └── settimer │ │ ├── SetTimerViewModel.kt │ │ ├── TimerUiState.kt │ │ ├── clipselect │ │ ├── ClipSelectAdapter.kt │ │ ├── ClipSelectViewHolder.kt │ │ └── TimerClipSelectFragment.kt │ │ ├── repeat │ │ ├── TimerRepeatAdapter.kt │ │ ├── TimerRepeatFragment.kt │ │ └── TimerRepeatViewHolder.kt │ │ └── timepicker │ │ ├── CenterSnapHelper.kt │ │ ├── ListUpdater.kt │ │ ├── NumberAdapter.kt │ │ ├── PickerViewHolder.kt │ │ ├── TimePeriodAdapter.kt │ │ └── TimePickerFragment.kt │ └── res │ ├── layout │ ├── fragment_modify_timer_bottom_sheet.xml │ ├── fragment_notification_permission_dialog.xml │ ├── fragment_time_picker.xml │ ├── fragment_timer.xml │ ├── fragment_timer_clip_select.xml │ ├── fragment_timer_repeat.xml │ ├── item_number_picker.xml │ ├── item_timer_clip_select.xml │ ├── item_timer_complete.xml │ ├── item_timer_repeat.xml │ └── item_timer_wait.xml │ └── navigation │ └── nav_graph_timer.xml ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 2 6 | indent_style = space 7 | max_line_length = 200 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.{kt,kts}] 12 | ij_kotlin_allow_trailing_comma = true 13 | ij_kotlin_allow_trailing_comma_on_call_site = true 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Bug" 3 | about: 앱에서 발생한 Issue를 설명해주세요. 4 | title: "[bug] App Bug Report" 5 | labels: Fix 6 | assignees: '' 7 | --- 8 | 9 | ## 🐞 BugFix 10 | 11 | ### 앱에서 발생한 Issue를 설명해주세요. 12 | 13 | A clear and concise description of what the bug is. 14 | 15 | 16 | ### Issue 재현 경로를 설명해주세요. 17 | Steps to reproduce the behavior: 18 | 1. Go to '...' 19 | 2. Click on '....' 20 | 3. Scroll down to '....' 21 | 4. See error 22 | 23 | 24 | ### 수정 후 예상되는 동작을 설명해주세요. 25 | A clear and concise description of what you expected to happen. 26 | 27 | 28 | ### 스크린샷 29 | If applicable, add screenshots to help explain your problem. 30 | 31 | 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Docs" 3 | about: 문서 작성 관련 작업내용을 설명해주세요. 4 | title: "[docs] Docs Task" 5 | labels: Docs 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## 📜 Docs 11 | 12 | ### 작업 내용을 설명해주세요. 13 | 14 | 15 | ### 비고 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Feature" 3 | about: 앱에서 추가할 기능을 설명해주세요. 4 | title: "[feat] Feature Request" 5 | labels: Feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## 🔍 Feature 11 | 12 | ### 추가할 기능에 대해 설명해주세요. 13 | 14 | 15 | 16 | ### Progress 17 | - [ ] todo1 18 | - [ ] todo2 19 | - [ ] todo3 20 | 21 | 22 | ### 비고 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Refactor.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Refactor" 3 | about: 앱에서 리팩토링할 내용을 설명해주세요. 4 | title: "[refactor] Refactor Request" 5 | labels: Refactor 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## ⚒️ Refactor 11 | 12 | ### 리팩토링할 내용에 대해 설명해주세요. 13 | 14 | 15 | 16 | ### Progress 17 | - [ ] todo1 18 | - [ ] todo2 19 | - [ ] todo3 20 | 21 | 22 | 23 | ### 비고 24 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## 📌 PR 요약 2 | 3 | 🌱 작업한 내용 4 | - 5 | 6 | 🌱 PR 포인트 7 | - 8 | 9 | ## 📸 스크린샷 10 | |스크린샷| 11 | |:--:| 12 | |파일첨부바람| 13 | 14 | ## 📮 관련 이슈 15 | - Resolved: #이슈번호 16 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/src/androidTest/java/org/sopt/linkmind/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.linkmind 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.platform.app.InstrumentationRegistry 5 | import junit.framework.TestCase.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 19 | assertEquals("org.sopt.linkmind", appContext.packageName) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/org/sopt/linkmind/SplashActivity.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.linkmind 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import androidx.appcompat.app.AppCompatActivity 6 | import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen 7 | import org.sopt.login.onboarding.LoginActivity 8 | 9 | class SplashActivity : AppCompatActivity() { 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | installSplashScreen() 12 | super.onCreate(savedInstanceState) 13 | val intent = Intent(this, LoginActivity::class.java) 14 | startActivity(intent) 15 | finish() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/org/sopt/linkmind/configuration/ToasterMessagingService.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.linkmind.configuration 2 | 3 | import com.google.firebase.messaging.FirebaseMessagingService 4 | import dagger.hilt.android.AndroidEntryPoint 5 | import kotlinx.coroutines.CoroutineScope 6 | import kotlinx.coroutines.Dispatchers 7 | import kotlinx.coroutines.launch 8 | import org.sopt.datastore.datastore.SecurityDataStore 9 | import javax.inject.Inject 10 | 11 | @AndroidEntryPoint 12 | class ToasterMessagingService : FirebaseMessagingService() { 13 | 14 | @Inject 15 | lateinit var dataStore: SecurityDataStore 16 | 17 | override fun onNewToken(token: String) { 18 | super.onNewToken(token) 19 | 20 | CoroutineScope(Dispatchers.IO).launch { dataStore.setDeviceToken(token) } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #191919 4 | -------------------------------------------------------------------------------- /app/src/test/java/org/sopt/linkmind/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.linkmind 2 | 3 | import junit.framework.TestCase.assertEquals 4 | import org.junit.Test 5 | 6 | /** 7 | * Example local unit test, which will execute on the development machine (host). 8 | * 9 | * See [testing documentation](http://d.android.com/tools/testing). 10 | */ 11 | class ExampleUnitTest { 12 | @Test 13 | fun addition_isCorrect() { 14 | assertEquals(4, 2 + 2) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /build-logic/convention/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /build-logic/convention/src/main/java/AndroidApplicationConventionPlugin.kt: -------------------------------------------------------------------------------- 1 | import com.android.build.api.dsl.ApplicationExtension 2 | import com.linkmind.convention.Const 3 | import com.linkmind.convention.configureKotlinAndroid 4 | import org.gradle.api.Plugin 5 | import org.gradle.api.Project 6 | import org.gradle.kotlin.dsl.configure 7 | 8 | internal class AndroidApplicationConventionPlugin : Plugin { 9 | 10 | override fun apply(target: Project) { 11 | with(target) { 12 | with(pluginManager) { 13 | apply("com.android.application") 14 | apply("org.jetbrains.kotlin.android") 15 | } 16 | 17 | extensions.configure { 18 | configureKotlinAndroid(this) 19 | defaultConfig.targetSdk = Const.targetSdk 20 | 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /build-logic/convention/src/main/java/AndroidHiltConventionPlugin.kt: -------------------------------------------------------------------------------- 1 | import com.linkmind.convention.libs 2 | import org.gradle.api.Plugin 3 | import org.gradle.api.Project 4 | import org.gradle.kotlin.dsl.dependencies 5 | 6 | class AndroidHiltConventionPlugin : Plugin { 7 | override fun apply(target: Project) { 8 | with(target) { 9 | with(pluginManager) { 10 | apply("com.google.devtools.ksp") 11 | apply("dagger.hilt.android.plugin") 12 | } 13 | 14 | dependencies { 15 | "implementation"(libs.findLibrary("hilt.android").get()) 16 | "ksp"(libs.findLibrary("hilt.compiler").get()) 17 | "testImplementation"(libs.findLibrary("hilt.testing").get()) 18 | "kspTest"(libs.findLibrary("hilt.testing.compiler").get()) 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /build-logic/convention/src/main/java/AndroidLibraryConventionPlugin.kt: -------------------------------------------------------------------------------- 1 | import com.android.build.gradle.LibraryExtension 2 | import com.linkmind.convention.Const 3 | import com.linkmind.convention.configureKotlinAndroid 4 | import org.gradle.api.Plugin 5 | import org.gradle.api.Project 6 | import org.gradle.kotlin.dsl.configure 7 | 8 | @Suppress("UNUSED") 9 | class AndroidLibraryConventionPlugin : Plugin { 10 | override fun apply(target: Project) { 11 | with(target) { 12 | with(pluginManager) { 13 | apply("com.android.library") 14 | apply("org.jetbrains.kotlin.android") 15 | } 16 | 17 | extensions.configure { 18 | configureKotlinAndroid(this) 19 | viewBinding.enable = true 20 | } 21 | } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /build-logic/convention/src/main/java/DataModuleConventionPlugin.kt: -------------------------------------------------------------------------------- 1 | 2 | import com.linkmind.convention.libs 3 | import org.gradle.api.Plugin 4 | import org.gradle.api.Project 5 | import org.gradle.kotlin.dsl.dependencies 6 | import org.gradle.kotlin.dsl.project 7 | 8 | internal class DataModuleConventionPlugin : Plugin { 9 | 10 | override fun apply(target: Project) { 11 | with(target) { 12 | with(pluginManager) { 13 | apply("linkmind.android.library") 14 | apply("linkmind.android.hilt") 15 | } 16 | 17 | dependencies { 18 | "implementation"(project(":core:model")) 19 | "implementation"(libs.findBundle("coroutine").get()) 20 | "implementation"(libs.findLibrary("timber").get()) 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /build-logic/convention/src/main/java/com/linkmind/convention/Const.kt: -------------------------------------------------------------------------------- 1 | package com.linkmind.convention 2 | 3 | import org.gradle.api.JavaVersion 4 | 5 | object Const { 6 | const val compileSdk = 34 7 | const val minSdk = 24 8 | const val targetSdk = 34 9 | const val JDK_VERSION = 17 10 | val JAVA_VERSION = JavaVersion.VERSION_17 11 | } 12 | -------------------------------------------------------------------------------- /build-logic/convention/src/main/java/com/linkmind/convention/ProjectExt.kt: -------------------------------------------------------------------------------- 1 | package com.linkmind.convention 2 | 3 | import org.gradle.api.Project 4 | import org.gradle.api.artifacts.VersionCatalog 5 | import org.gradle.api.artifacts.VersionCatalogsExtension 6 | import org.gradle.kotlin.dsl.getByType 7 | 8 | val Project.libs: VersionCatalog 9 | get() = extensions.getByType().named("libs") 10 | -------------------------------------------------------------------------------- /build-logic/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | versionCatalogs { 7 | create("libs") { 8 | from(files("../gradle/libs.versions.toml")) 9 | } 10 | } 11 | } 12 | 13 | rootProject.name = "build-logic" 14 | include(":convention") 15 | -------------------------------------------------------------------------------- /core/auth/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core/auth/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.android.library) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.auth" 9 | } 10 | -------------------------------------------------------------------------------- /core/auth/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/auth/src/main/java/org/sopt/auth/model/Auth.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.auth.model 2 | 3 | data class Auth( 4 | val socialToken: String, 5 | val deviceToken: String, 6 | val socialType: String, 7 | ) 8 | -------------------------------------------------------------------------------- /core/auth/src/main/java/org/sopt/auth/model/Token.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.auth.model 2 | 3 | data class Token( 4 | val accessToken: String, 5 | val refreshToken: String, 6 | val deviceToken: String, 7 | ) 8 | -------------------------------------------------------------------------------- /core/auth/src/main/java/org/sopt/auth/model/UserData.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.auth.model 2 | 3 | data class UserData( 4 | val userId: Int, 5 | val isRegistered: Boolean, 6 | val fcmIsAllowed: Boolean, 7 | ) 8 | -------------------------------------------------------------------------------- /core/auth/src/main/java/org/sopt/auth/repository/AuthRepository.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.auth.repository 2 | 3 | import org.sopt.auth.model.Auth 4 | import org.sopt.auth.model.Token 5 | import org.sopt.auth.model.UserData 6 | 7 | interface AuthRepository { 8 | suspend fun authenticate(auth: Auth): Result?> 9 | suspend fun signout(): Result 10 | suspend fun withdraw(): Result 11 | suspend fun saveToken(token: Token) 12 | 13 | suspend fun getToken(): Token 14 | suspend fun clearToken() 15 | } 16 | -------------------------------------------------------------------------------- /core/authimpl/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core/authimpl/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.android.library) 4 | alias(libs.plugins.linkmind.android.hilt) 5 | alias(libs.plugins.kotlin.android) 6 | alias(libs.plugins.kotlin.serialization) 7 | } 8 | 9 | android { 10 | namespace = "org.sopt.authimpl" 11 | } 12 | 13 | dependencies { 14 | implementation(projects.core.network) 15 | implementation(projects.core.auth) 16 | implementation(projects.core.datastore) 17 | implementation(libs.bundles.coroutine) 18 | implementation(libs.retrofit.kotlin.serialization) 19 | } 20 | -------------------------------------------------------------------------------- /core/authimpl/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/authimpl/consumer-rules.pro -------------------------------------------------------------------------------- /core/authimpl/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/authimpl/src/main/java/org/sopt/authimpl/di/ApiModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.authimpl.di 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.authimpl.sourceimpl.remote.api.AuthService 8 | import org.sopt.network.di.AuthLinkMindRetrofit 9 | import retrofit2.Retrofit 10 | import javax.inject.Singleton 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | object ApiModule { 15 | @Provides 16 | @Singleton 17 | fun provideAuthService(@AuthLinkMindRetrofit retrofit: Retrofit): AuthService = 18 | retrofit.create(AuthService::class.java) 19 | } 20 | -------------------------------------------------------------------------------- /core/authimpl/src/main/java/org/sopt/authimpl/di/RepositoryModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.authimpl.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.auth.repository.AuthRepository 8 | import org.sopt.authimpl.repository.AuthRepositoryImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class RepositoryModule { 14 | @Binds 15 | @Singleton 16 | abstract fun bindsAuthRepository(authRepository: AuthRepositoryImpl): AuthRepository 17 | } 18 | -------------------------------------------------------------------------------- /core/authimpl/src/main/java/org/sopt/authimpl/model/request/RequestPostAuthDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.authimpl.model.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.auth.model.Auth 6 | 7 | @Serializable 8 | data class RequestPostAuthDto( 9 | @SerialName("socialType") 10 | val socialType: String, 11 | @SerialName("fcmToken") 12 | val fcmToken: String, 13 | ) { 14 | companion object { 15 | fun Auth.toDataModel() = 16 | RequestPostAuthDto( 17 | this.socialType, 18 | this.deviceToken, 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/authimpl/src/main/java/org/sopt/authimpl/model/response/ResponsePostSignOutDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.authimpl.model.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class ResponsePostSignOutDto( 8 | @SerialName("code") 9 | val code: Int, 10 | @SerialName("message") 11 | val message: String, 12 | @SerialName("data") 13 | val data: Unit?, 14 | ) 15 | -------------------------------------------------------------------------------- /core/authimpl/src/main/java/org/sopt/authimpl/source/local/AuthLocalDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.authimpl.source.local 2 | 3 | import org.sopt.auth.model.Token 4 | 5 | interface AuthLocalDataSource { 6 | suspend fun save(token: Token) 7 | 8 | suspend fun getToken(): Token 9 | suspend fun clear() 10 | } 11 | -------------------------------------------------------------------------------- /core/authimpl/src/main/java/org/sopt/authimpl/source/remote/AuthRemoteDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.authimpl.source.remote 2 | 3 | import org.sopt.authimpl.model.request.RequestPostAuthDto 4 | import org.sopt.authimpl.model.response.ResponsePostAuthDto 5 | import org.sopt.authimpl.model.response.ResponsePostSignOutDto 6 | import org.sopt.network.model.response.base.BaseResponse 7 | 8 | interface AuthRemoteDataSource { 9 | suspend fun authenticate( 10 | socialToken: String, 11 | postAuthDto: RequestPostAuthDto, 12 | ): BaseResponse 13 | 14 | suspend fun signout(): ResponsePostSignOutDto 15 | 16 | suspend fun withdraw(): BaseResponse 17 | } 18 | -------------------------------------------------------------------------------- /core/common/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core/common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.android.library) 4 | alias(libs.plugins.kotlin.android) 5 | alias(libs.plugins.linkmind.android.hilt) 6 | } 7 | 8 | android { 9 | namespace = "org.sopt.common" 10 | } 11 | 12 | dependencies { 13 | 14 | implementation(libs.core.ktx) 15 | implementation(libs.appcompat) 16 | implementation(libs.material) 17 | implementation(libs.bundles.coroutine) 18 | implementation(libs.timber) 19 | } 20 | -------------------------------------------------------------------------------- /core/common/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/common/consumer-rules.pro -------------------------------------------------------------------------------- /core/common/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/common/src/main/java/org/sopt/common/intentprovider/IntentProvider.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.common.intentprovider 2 | 3 | import android.content.Intent 4 | 5 | interface IntentProvider { 6 | fun getIntent(): Intent 7 | } 8 | -------------------------------------------------------------------------------- /core/common/src/main/java/org/sopt/common/intentprovider/Qualifier.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.common.intentprovider 2 | 3 | import javax.inject.Qualifier 4 | 5 | @Qualifier 6 | @Retention(AnnotationRetention.BINARY) 7 | annotation class LOGIN 8 | 9 | @Qualifier 10 | @Retention(AnnotationRetention.BINARY) 11 | annotation class MAIN 12 | -------------------------------------------------------------------------------- /core/common/src/main/java/org/sopt/common/util/Sample.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.common.util 2 | 3 | // 공통 유틸 파일 4 | -------------------------------------------------------------------------------- /core/common/src/main/java/org/sopt/common/util/StringExt.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.common.util 2 | 3 | fun String.delSpace() = this.replace(" ", "").replace("\n", "") 4 | -------------------------------------------------------------------------------- /core/common/src/main/java/org/sopt/common/util/throttleValue/ThrottleValue.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.common.util.throttleValue 2 | 3 | import kotlinx.coroutines.Dispatchers 4 | import kotlinx.coroutines.GlobalScope 5 | import kotlinx.coroutines.Job 6 | import kotlinx.coroutines.delay 7 | import kotlinx.coroutines.launch 8 | 9 | class ThrottleValue { 10 | private var debounceJob: Job? = null 11 | fun setDelay(value: T, delay: Long, action: (T) -> Unit) { 12 | debounceJob?.cancel() 13 | debounceJob = GlobalScope.launch(Dispatchers.Main) { 14 | delay(delay) 15 | action(value) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core/datastore/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core/datastore/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.android.library) 4 | alias(libs.plugins.linkmind.android.hilt) 5 | alias(libs.plugins.kotlin.android) 6 | } 7 | 8 | android { 9 | namespace = "org.sopt.datastore" 10 | } 11 | 12 | dependencies { 13 | 14 | implementation(libs.bundles.coroutine) 15 | implementation(libs.bundles.datastore) 16 | ksp(libs.encrypted.datastore.preference.ksp) 17 | implementation(libs.bundles.encrypted.datastore) 18 | } 19 | -------------------------------------------------------------------------------- /core/datastore/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/datastore/consumer-rules.pro -------------------------------------------------------------------------------- /core/datastore/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/designsystem/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core/designsystem/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.android.library) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.mainfeature" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(projects.core.ui) 16 | implementation(projects.core.common) 17 | implementation(libs.androidx.appcompat) 18 | implementation(libs.androidx.core.ktx) 19 | implementation(libs.androidx.constraintlayout) 20 | implementation(libs.androidx.recyclerview) 21 | implementation(libs.google.material) 22 | implementation(libs.coil) 23 | implementation(libs.timber) 24 | } 25 | -------------------------------------------------------------------------------- /core/designsystem/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/consumer-rules.pro -------------------------------------------------------------------------------- /core/designsystem/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /core/designsystem/src/main/java/designsystem/components/bottomsheet/BottomSheetType.kt: -------------------------------------------------------------------------------- 1 | package designsystem.components.bottomsheet 2 | 3 | enum class BottomSheetType { 4 | LINK, 5 | CLIP, 6 | } 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/java/designsystem/components/button/state/LinkMIndFullWidthButtonState.kt: -------------------------------------------------------------------------------- 1 | package designsystem.components.button.state 2 | enum class LinkMIndFullWidthButtonState { 3 | ENABLE_PRIMARY, ENABLE_BLACK, DISABLE 4 | } 5 | -------------------------------------------------------------------------------- /core/designsystem/src/main/java/designsystem/components/button/state/LinkMindButtonState.kt: -------------------------------------------------------------------------------- 1 | package designsystem.components.button.state 2 | 3 | enum class LinkMindButtonState { 4 | ENABLE, DISABLE 5 | } 6 | -------------------------------------------------------------------------------- /core/designsystem/src/main/java/designsystem/components/edittext/state/LinkMindEditTextState.kt: -------------------------------------------------------------------------------- 1 | package designsystem.components.edittext.state 2 | 3 | enum class LinkMindEditTextState { 4 | ENABLE, ERROR 5 | } 6 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/anim/from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/anim/from_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/anim/from_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/anim/to_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/anim/to_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/anim/to_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_alarm_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_alert_18_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_arrow_18_svg.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_arrow_20.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_arrow_black_svg.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_arrow_left_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_cancle_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 15 | 21 | 22 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_check_18_primary.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_check_18_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_close_20.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_close_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_edit_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_ellipse_18.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_ellipse_99.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_gnb_back_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_home_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 16 | 17 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_my_select_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_my_unselectd_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_plus_18_orange.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_plus_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_plus_white_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 14 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_share.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_toggle_ellipse_18.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_toggle_off_background.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ic_toggle_on_background.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_clip_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_clip_empty.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_link_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_link_empty.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_link_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_link_thumb.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_login.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_mypage_alarm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_mypage_alarm.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_mypage_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_mypage_profile.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_notification_permission.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_notification_permission.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_onboarding_first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_onboarding_first.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_onboarding_second.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_onboarding_second.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_onboarding_third.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_onboarding_third.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_search_none_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_search_none_result.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_timer_none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_timer_none.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_toast.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_toast.jpg -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_toaster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_toaster.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/img_toaster_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/drawable/img_toaster_title.png -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/progress_bar_horizontal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/ripple_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/sel_bnv_clip.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/sel_bnv_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/sel_bnv_my.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/sel_bnv_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/sel_bnv_text_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/sel_bnv_timer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_gray_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_grey900_fill_8_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_kakao_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals050_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals050_line_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals100_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals100_line_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals200_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals850_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | /> 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals_fill_8_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals_fill_error_line_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_neutrals_fill_top20_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_primary_fill_4_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_primary_fill_8_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_red_fill_8_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_white_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/drawable/shape_white_fill_2_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/font_suit_bold.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/font_suit_extrabold.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/font_suit_medium.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/font_suit_regular.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/font_suit_semibold.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/suit_bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/font/suit_bold.otf -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/suit_extrabold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/font/suit_extrabold.otf -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/suit_medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/font/suit_medium.otf -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/suit_regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/font/suit_regular.otf -------------------------------------------------------------------------------- /core/designsystem/src/main/res/font/suit_semibold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/font/suit_semibold.otf -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/designsystem/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /core/designsystem/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/values-v31/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/xml/backup_rules.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | -------------------------------------------------------------------------------- /core/designsystem/src/main/res/xml/data_extraction_rules.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 12 | 13 | 19 | -------------------------------------------------------------------------------- /core/model/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core/model/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.java.library) 4 | } 5 | 6 | dependencies { 7 | } 8 | -------------------------------------------------------------------------------- /core/model/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/model/consumer-rules.pro -------------------------------------------------------------------------------- /core/model/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/category/Category.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.category 2 | 3 | data class Category( 4 | val categoryId: Long? = 0, 5 | val categoryTitle: String?, 6 | var toastNum: Long, 7 | ) 8 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/category/CategoryChangePriority.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.category 2 | 3 | data class CategoryChangePriority( 4 | val categoryId: Long, 5 | val newPriority: Int, 6 | ) 7 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/category/CategoryDuplicate.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.category 2 | 3 | data class CategoryDuplicate( 4 | val isDuplicate: Boolean, 5 | ) 6 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/category/CategoryLink.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.category 2 | 3 | data class CategoryLink( 4 | val toastId: Long, 5 | val categoryTitle: String?, 6 | val isRead: Boolean, 7 | val linkUrl: String?, 8 | val toastTitle: String, 9 | val thumbnailUrl: String?, 10 | ) 11 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/category/CategoryLinkList.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.category 2 | 3 | data class CategoryLinkList( 4 | val allToastNum: Long, 5 | val toastListDto: List, 6 | ) 7 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/category/CategoryList.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.category 2 | 3 | data class CategoryList( 4 | val toastNumberInEntire: Long, 5 | val categories: List, 6 | ) 7 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/category/SearchResultList.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.category 2 | 3 | data class SearchResultList( 4 | val toasts: List?, 5 | val categories: List?, 6 | val keyword: String?, 7 | ) 8 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/category/Toast.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.category 2 | 3 | data class Toast( 4 | val toastId: Long, 5 | val categoryTitle: String?, 6 | val isRead: Boolean?, 7 | val linkUrl: String?, 8 | val toastTitle: String?, 9 | val thumbnailUrl: String?, 10 | ) 11 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/home/MainPageData.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.home 2 | 3 | import org.sopt.model.category.Category 4 | 5 | data class MainPageData( 6 | val nickName: String, 7 | val readToastNum: Int, 8 | val allToastNum: Int, 9 | val mainCategoryDto: List, 10 | ) 11 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/home/PopupInfo.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.home 2 | 3 | data class PopupInfo( 4 | val popupId: Int, 5 | val popupImage: String, 6 | val popupActiveStartDate: String, 7 | val popupActiveEndDate: String, 8 | val popupLinkUrl: String, 9 | ) 10 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/home/PopupInvisible.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.home 2 | 3 | data class PopupInvisible( 4 | val popupId: Int, 5 | val popupHideUntil: String, 6 | ) 7 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/home/RecentSavedLink.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.home 2 | 3 | data class RecentSavedLink( 4 | val toastId: Long, 5 | val toastTitle: String, 6 | val linkUrl: String, 7 | val isRead: Boolean, 8 | val categoryTitle: String?, 9 | val thumbnailUrl: String?, 10 | ) 11 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/home/RecommendLink.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.home 2 | 3 | data class RecommendLink( 4 | val siteId: Long, 5 | val siteTitle: String? = "", 6 | val siteSub: String? = "", 7 | val siteImg: String? = "", 8 | val siteUrl: String? = "", 9 | ) 10 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/home/WeekBestLink.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.home 2 | 3 | data class WeekBestLink( 4 | val toastId: Long, 5 | val toastTitle: String, 6 | val toastImg: String? = "", 7 | val toastLink: String, 8 | ) 9 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/timer/Clip.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.timer 2 | 3 | import org.sopt.model.category.Category 4 | 5 | data class Clip( 6 | val id: Long, 7 | val name: String, 8 | val count: Long, 9 | var isSelected: Boolean, 10 | ) 11 | 12 | fun List.toUiModel(): List = this.map { 13 | Clip( 14 | id = it.categoryId ?: 0, 15 | name = it.categoryTitle ?: "", 16 | count = it.toastNum, 17 | isSelected = false, 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/timer/Repeat.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.timer 2 | 3 | data class Repeat( 4 | val period: String, 5 | var isSelected: Boolean, 6 | ) 7 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/timer/Timer.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.timer 2 | 3 | data class Timer( 4 | val id: Int, 5 | val categoryId: Int, 6 | val remindTime: String, 7 | val remindDate: String?, 8 | val remindDates: String?, 9 | val comment: String?, 10 | val isAlarm: Boolean?, 11 | ) 12 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/timer/TimerData.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.timer 2 | 3 | data class TimerData( 4 | val categoryId: Long?, 5 | val remindTime: String, 6 | val remindDates: List, 7 | ) 8 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/user/MyPageData.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.user 2 | 3 | data class MyPageData( 4 | val nickname: String, 5 | val profile: String, 6 | val allReadToast: Long, 7 | val thisWeekendRead: Long, 8 | val thisWeekendSaved: Long, 9 | ) 10 | -------------------------------------------------------------------------------- /core/model/src/main/java/org/sopt/model/user/SettingPageData.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.model.user 2 | 3 | data class SettingPageData( 4 | val nickname: String, 5 | val fcmIsAllowed: Boolean, 6 | ) 7 | -------------------------------------------------------------------------------- /core/network/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core/network/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.android.library) 4 | alias(libs.plugins.linkmind.android.hilt) 5 | alias(libs.plugins.kotlin.serialization) 6 | } 7 | 8 | android { 9 | namespace = "org.sopt.core.network" 10 | } 11 | 12 | dependencies { 13 | implementation(projects.core.common) 14 | implementation(projects.core.datastore) 15 | implementation(libs.bundles.coroutine) 16 | implementation(libs.kotlinx.serialization.json) 17 | implementation(libs.retrofit.core) 18 | implementation(libs.retrofit.kotlin.serialization) 19 | implementation(libs.okhttp.logging) 20 | implementation(libs.timber) 21 | implementation(libs.process.phoenix) 22 | } 23 | -------------------------------------------------------------------------------- /core/network/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/network/consumer-rules.pro -------------------------------------------------------------------------------- /core/network/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/network/src/main/java/org/sopt/network/di/ApiModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.network.di 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.network.service.TokenRefreshService 8 | import retrofit2.Retrofit 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | object ApiModule { 14 | @Provides 15 | @Singleton 16 | fun provideTokenRefreshService(@LinkMindRetrofit retrofit: Retrofit) = 17 | retrofit.create(TokenRefreshService::class.java) 18 | } 19 | -------------------------------------------------------------------------------- /core/network/src/main/java/org/sopt/network/di/Qualifier.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.network.di 2 | 3 | import javax.inject.Qualifier 4 | 5 | @Qualifier 6 | @Retention(AnnotationRetention.BINARY) 7 | annotation class NoneAuthOkHttpClient 8 | 9 | @Qualifier 10 | @Retention(AnnotationRetention.BINARY) 11 | annotation class AuthOkHttpClient 12 | 13 | @Qualifier 14 | @Retention(AnnotationRetention.BINARY) 15 | annotation class Logging 16 | 17 | @Qualifier 18 | @Retention(AnnotationRetention.BINARY) 19 | annotation class Auth 20 | 21 | @Qualifier 22 | @Retention(AnnotationRetention.BINARY) 23 | annotation class LinkMindRetrofit 24 | 25 | @Qualifier 26 | @Retention(AnnotationRetention.BINARY) 27 | annotation class AuthLinkMindRetrofit 28 | -------------------------------------------------------------------------------- /core/network/src/main/java/org/sopt/network/model/response/ResponsePostAuthRefreshDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.network.model.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class ResponsePostAuthRefreshDto( 8 | @SerialName("accessToken") 9 | val accessToken: String, 10 | @SerialName("refreshToken") 11 | val refreshToken: String, 12 | ) 13 | -------------------------------------------------------------------------------- /core/network/src/main/java/org/sopt/network/model/response/base/BaseResponse.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.network.model.response.base 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class BaseResponse( 8 | @SerialName("code") 9 | val code: Int, 10 | @SerialName("message") 11 | val message: String, 12 | @SerialName("data") 13 | val data: T? = null, 14 | ) 15 | -------------------------------------------------------------------------------- /core/network/src/main/java/org/sopt/network/service/TokenRefreshService.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.network.service 2 | 3 | import org.sopt.network.model.response.ResponsePostAuthRefreshDto 4 | import org.sopt.network.model.response.base.BaseResponse 5 | import retrofit2.http.Header 6 | import retrofit2.http.POST 7 | 8 | interface TokenRefreshService { 9 | @POST("auth/token") 10 | suspend fun postAuthRefresh( 11 | @Header("refreshToken") refreshToken: String, 12 | ): BaseResponse 13 | } 14 | -------------------------------------------------------------------------------- /core/ui/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /core/ui/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/core/ui/consumer-rules.pro -------------------------------------------------------------------------------- /core/ui/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /core/ui/src/main/java/org/sopt/ui/intent/IntentExt.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.ui.intent 2 | 3 | import android.content.Intent 4 | import android.os.Build 5 | import android.os.Parcelable 6 | 7 | fun Intent.getParcelable(key: String, c: Class): T? = when { 8 | Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> getParcelableExtra(key, c) 9 | else -> getParcelableExtra(key) as? T 10 | } 11 | -------------------------------------------------------------------------------- /core/ui/src/main/java/org/sopt/ui/view/CaculateMarignDialog.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.ui.view 2 | 3 | import android.content.res.Resources 4 | 5 | fun caculateMarignDialog(dpMargin: Float): Int { 6 | val dpToPixel = Resources.getSystem().displayMetrics.density 7 | val dialogHorizontalMarginInPixels = (dpToPixel * dpMargin + 0.5f).toInt() 8 | val deviceWidth = Resources.getSystem().displayMetrics.widthPixels 9 | return deviceWidth - 2 * dialogHorizontalMarginInPixels 10 | } 11 | -------------------------------------------------------------------------------- /core/ui/src/main/java/org/sopt/ui/view/ItemDiffCallback.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.ui.view 2 | 3 | import androidx.recyclerview.widget.DiffUtil 4 | 5 | class ItemDiffCallback( 6 | val onItemsTheSame: (T, T) -> Boolean, 7 | val onContentsTheSame: (T, T) -> Boolean, 8 | ) : DiffUtil.ItemCallback() { 9 | override fun areItemsTheSame( 10 | oldItem: T, 11 | newItem: T, 12 | ): Boolean = onItemsTheSame(oldItem, newItem) 13 | 14 | override fun areContentsTheSame( 15 | oldItem: T, 16 | newItem: T, 17 | ): Boolean = onContentsTheSame(oldItem, newItem) 18 | } 19 | -------------------------------------------------------------------------------- /core/ui/src/main/java/org/sopt/ui/view/ThrottleClickListner.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.ui.view 2 | 3 | import android.view.View 4 | 5 | fun View.onThrottleClick( 6 | onClick: (v: View) -> Unit, 7 | ) { 8 | val listener = View.OnClickListener { onClick(it) } 9 | setOnClickListener(OnThrottleClickListener(listener)) 10 | } 11 | class OnThrottleClickListener( 12 | private val clickListener: View.OnClickListener, 13 | private val interval: Long = 300L, 14 | ) : View.OnClickListener { 15 | 16 | private var clicked = false 17 | override fun onClick(v: View?) { 18 | if (!clicked) { 19 | clicked = true 20 | v?.run { 21 | postDelayed( 22 | { clicked = false }, 23 | interval, 24 | ) 25 | clickListener.onClick(v) 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /core/ui/src/main/java/org/sopt/ui/view/UiState.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.ui.view 2 | 3 | sealed interface UiState { 4 | object Empty : UiState 5 | 6 | object Loading : UiState 7 | 8 | data class Success( 9 | val data: T, 10 | ) : UiState 11 | 12 | data class Failure( 13 | val msg: String, 14 | ) : UiState 15 | 16 | fun getUiStateModel(): UiStateModel { 17 | return UiStateModel( 18 | this is Empty, 19 | this is Loading, 20 | this is Success, 21 | this is Failure, 22 | ) 23 | } 24 | } 25 | 26 | data class UiStateModel( 27 | val isEmpty: Boolean = false, 28 | val isLoading: Boolean = true, 29 | val isSuccess: Boolean = false, 30 | val isFailure: Boolean = false, 31 | ) 32 | -------------------------------------------------------------------------------- /data-local/linkminddata-local/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data-local/linkminddata-local/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.linkminddatalocal" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.data.linkminddata) 13 | implementation(libs.retrofit.kotlin.serialization) 14 | } 15 | -------------------------------------------------------------------------------- /data-local/linkminddata-local/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data-local/linkminddata-local/consumer-rules.pro -------------------------------------------------------------------------------- /data-local/linkminddata-local/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data-local/linkminddata-local/src/main/java/org/sopt/linkminddatalocal/di/DataSourceModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.linkminddatalocal.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.linkminddata.source.local.DummyLocalDataSource 8 | import org.sopt.linkminddatalocal.source.DummyLocalDataSourceImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | internal abstract class DataSourceModule { 14 | @Singleton 15 | @Binds 16 | abstract fun bindsDummyLocalDataSource(dummyLocalDataSource: DummyLocalDataSourceImpl): DummyLocalDataSource 17 | } 18 | -------------------------------------------------------------------------------- /data-local/linkminddata-local/src/main/java/org/sopt/linkminddatalocal/source/DummyLocalDataSourceImpl.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.linkminddatalocal.source 2 | 3 | import org.sopt.linkminddata.model.local.Dummy 4 | import org.sopt.linkminddata.source.local.DummyLocalDataSource 5 | import javax.inject.Inject 6 | 7 | class DummyLocalDataSourceImpl @Inject constructor() : DummyLocalDataSource { 8 | override suspend fun getDummy(): Dummy = Dummy("더미") 9 | } 10 | -------------------------------------------------------------------------------- /data-remote/category/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data-remote/category/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.remote.category" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.data.category) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data-remote/category/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data-remote/category/consumer-rules.pro -------------------------------------------------------------------------------- /data-remote/category/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/api/SearchService.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.api 2 | 3 | import org.sopt.dataremote.category.response.ResponseSearchDto 4 | import org.sopt.network.model.response.base.BaseResponse 5 | import retrofit2.http.GET 6 | import retrofit2.http.Query 7 | 8 | interface SearchService { 9 | @GET("/main/search") 10 | suspend fun getSearchResult(@Query("query") query: String): BaseResponse 11 | } 12 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/datasource/RemoteSearchDataSourceImpl.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.datasource 2 | 3 | import org.sopt.data.category.datasource.RemoteSearchDataSource 4 | import org.sopt.dataremote.category.api.SearchService 5 | import org.sopt.dataremote.category.response.toCoreModel 6 | import org.sopt.model.category.SearchResultList 7 | import javax.inject.Inject 8 | 9 | class RemoteSearchDataSourceImpl @Inject constructor( 10 | private val searchService: SearchService, 11 | ) : RemoteSearchDataSource { 12 | override suspend fun getSearchResult(query: String): SearchResultList { 13 | val response = searchService.getSearchResult(query) 14 | return response.data!!.toCoreModel() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/di/CategoryDataSourceModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.data.category.datasource.RemoteCategoryDataSource 8 | import org.sopt.dataremote.category.datasource.RemoteCategoryDataSourceImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class CategoryDataSourceModule { 14 | @Singleton 15 | @Binds 16 | abstract fun bindRemoteCategoryDatasource( 17 | remoteCategoryDataSourceImpl: RemoteCategoryDataSourceImpl, 18 | ): RemoteCategoryDataSource 19 | } 20 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/di/CategoryServiceModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.di 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.dataremote.category.api.CategoryService 8 | import org.sopt.network.di.AuthLinkMindRetrofit 9 | import retrofit2.Retrofit 10 | import javax.inject.Singleton 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | object CategoryServiceModule { 15 | 16 | @Singleton 17 | @Provides 18 | fun provideCategoryService(@AuthLinkMindRetrofit retrofit: Retrofit): CategoryService = 19 | retrofit.create(CategoryService::class.java) 20 | } 21 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/di/SearchDataSourceModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.data.category.datasource.RemoteSearchDataSource 8 | import org.sopt.dataremote.category.datasource.RemoteSearchDataSourceImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class SearchDataSourceModule { 14 | @Singleton 15 | @Binds 16 | abstract fun bindRemoteSearchDatasource( 17 | remoteSearchDataSourceImpl: RemoteSearchDataSourceImpl, 18 | ): RemoteSearchDataSource 19 | } 20 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/di/SearchServiceModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.di 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.dataremote.category.api.SearchService 8 | import org.sopt.network.di.AuthLinkMindRetrofit 9 | import retrofit2.Retrofit 10 | import javax.inject.Singleton 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | object SearchServiceModule { 15 | 16 | @Singleton 17 | @Provides 18 | fun provideSearchService(@AuthLinkMindRetrofit retrofit: Retrofit): SearchService = 19 | retrofit.create(SearchService::class.java) 20 | } 21 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/request/RequestCategoryDeleteDTO.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestCategoryDeleteDTO( 8 | @SerialName("deleteCategoryDto") 9 | val deleteCategoryList: Long, 10 | ) 11 | 12 | fun Long.toRequestDTO() = RequestCategoryDeleteDTO(deleteCategoryList = this) 13 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/request/RequestCategoryDuplicateDTO.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestCategoryDuplicateDTO( 8 | @SerialName("title") 9 | val title: String, 10 | ) 11 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/request/RequestCategoryEditTitleDTO.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestCategoryEditTitleDTO( 8 | @SerialName("categoryId") 9 | val categoryId: Long, 10 | @SerialName("newTitle") 11 | val categoryTitle: String, 12 | ) 13 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/request/RequestCategoryPriorityDTO.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.model.category.CategoryChangePriority 6 | 7 | @Serializable 8 | data class RequestCategoryPriorityDTO( 9 | @SerialName("categoryId") 10 | val categoryId: Long, 11 | @SerialName("newPriority") 12 | val newPriority: Int, 13 | 14 | ) 15 | fun RequestCategoryPriorityDTO.toRequestDTO() = CategoryChangePriority( 16 | categoryId = this.categoryId, 17 | newPriority = this.newPriority, 18 | ) 19 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/request/RequestCategoryTitleDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | @Serializable 6 | data class RequestCategoryTitleDto( 7 | @SerialName("categoryTitle") 8 | val categoryTitle: String?, 9 | ) 10 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/request/RequestSearchDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestSearchDto( 8 | @SerialName("query") 9 | val query: RequestSearchDto, 10 | ) 11 | -------------------------------------------------------------------------------- /data-remote/category/src/main/java/org/sopt/dataremote/category/response/ResponseCategoryDuplicateDTO.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.dataremote.category.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.model.category.CategoryDuplicate 6 | 7 | @Serializable 8 | data class ResponseCategoryDuplicateDTO( 9 | @SerialName("isDupicated") 10 | val isDuplicated: Boolean, 11 | ) 12 | 13 | internal fun ResponseCategoryDuplicateDTO.toCoreModel() = CategoryDuplicate(isDuplicate = this.isDuplicated) 14 | -------------------------------------------------------------------------------- /data-remote/home/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data-remote/home/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.remote.home" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.data.home) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data-remote/home/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data-remote/home/consumer-rules.pro -------------------------------------------------------------------------------- /data-remote/home/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data-remote/home/src/main/java/org/sopt/remote/home/request/RequestPopupInvisibleDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.home.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestPopupInvisibleDto( 8 | @SerialName("popupId") 9 | val popupId: Long, 10 | @SerialName("hideDate") 11 | val hideDate: Long, 12 | ) 13 | -------------------------------------------------------------------------------- /data-remote/home/src/main/java/org/sopt/remote/home/response/ResponsePopupInvisibleDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.home.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.model.home.PopupInvisible 6 | 7 | @Serializable 8 | data class ResponsePopupInvisibleDto( 9 | @SerialName("popupId") 10 | val popupId: Int, 11 | @SerialName("hideUntil") 12 | val hideUntil: String, 13 | ) 14 | 15 | internal fun ResponsePopupInvisibleDto.toCoreModel() = PopupInvisible( 16 | popupId = popupId, 17 | popupHideUntil = hideUntil, 18 | ) 19 | -------------------------------------------------------------------------------- /data-remote/home/src/main/java/org/sopt/remote/home/response/ResponseRecommendLinkDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.home.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.model.home.RecommendLink 6 | 7 | @Serializable 8 | data class ResponseRecommendLinkDto( 9 | @SerialName("siteId") 10 | val siteId: Long, 11 | @SerialName("siteTitle") 12 | val siteTitle: String?, 13 | @SerialName("siteSub") 14 | val siteSub: String?, 15 | @SerialName("siteImg") 16 | val siteImg: String?, 17 | @SerialName("siteUrl") 18 | val siteUrl: String?, 19 | ) 20 | 21 | internal fun ResponseRecommendLinkDto.toCoreModel() = RecommendLink( 22 | siteId = siteId, 23 | siteTitle = siteTitle, 24 | siteSub = siteSub, 25 | siteImg = siteImg, 26 | siteUrl = siteUrl, 27 | ) 28 | -------------------------------------------------------------------------------- /data-remote/home/src/main/java/org/sopt/remote/home/response/ResponseWeekBestLinkDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.home.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.model.home.WeekBestLink 6 | 7 | @Serializable 8 | data class ResponseWeekBestLinkDto( 9 | @SerialName("linkId") 10 | val linkId: Long, 11 | @SerialName("linkTitle") 12 | val linkTitle: String, 13 | @SerialName("linkImg") 14 | val linkImg: String?, 15 | @SerialName("linkUrl") 16 | val linkUrl: String, 17 | ) 18 | 19 | internal fun ResponseWeekBestLinkDto.toCoreModel() = WeekBestLink( 20 | toastId = linkId, 21 | toastTitle = linkTitle, 22 | toastImg = linkImg, 23 | toastLink = linkUrl, 24 | ) 25 | -------------------------------------------------------------------------------- /data-remote/link/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data-remote/link/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.remote.link" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.data.link) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data-remote/link/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data-remote/link/consumer-rules.pro -------------------------------------------------------------------------------- /data-remote/link/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/di/LinkDataSourceModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.data.link.datasource.RemoteLinkDataSource 8 | import org.sopt.remote.link.datasource.RemoteLinkDataSourceImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class LinkDataSourceModule { 14 | @Singleton 15 | @Binds 16 | abstract fun bindRemoteLectureProviderDatasource( 17 | remoteLinkDataSourceImpl: RemoteLinkDataSourceImpl, 18 | ): RemoteLinkDataSource 19 | } 20 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/di/LinkServiceModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.di 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.network.di.AuthLinkMindRetrofit 8 | import org.sopt.remote.link.api.LinkService 9 | import retrofit2.Retrofit 10 | import javax.inject.Singleton 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | object LinkServiceModule { 15 | 16 | @Singleton 17 | @Provides 18 | fun provideCategoryService(@AuthLinkMindRetrofit retrofit: Retrofit): LinkService = 19 | retrofit.create(LinkService::class.java) 20 | } 21 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/request/RequestIsReadDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestIsReadDto( 8 | @SerialName("toastId") 9 | val toastId: Long, 10 | @SerialName("isRead") 11 | val isRead: Boolean, 12 | ) 13 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/request/RequestPatchCategoryDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestPatchCategoryDto( 8 | @SerialName("toastId") 9 | val toastId: Long, 10 | @SerialName("categoryId") 11 | val categoryId: Long, 12 | ) 13 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/request/RequestPatchTitleDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestPatchTitleDto( 8 | @SerialName("toastId") 9 | val toastId: Long, 10 | @SerialName("title") 11 | val title: String, 12 | ) 13 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/request/RequestWriteDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestWriteDto( 8 | @SerialName("linkUrl") 9 | val linkUrl: String, 10 | @SerialName("categoryId") 11 | val categoryId: Long?, 12 | ) 13 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/response/ResponseIsReadDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class ResponseIsReadDto( 8 | @SerialName("isRead") 9 | val isRead: Boolean, 10 | ) 11 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/response/ResponsePatchCategoryDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class ResponsePatchCategoryDto( 8 | @SerialName("categoryId") 9 | val categoryId: Long, 10 | ) 11 | -------------------------------------------------------------------------------- /data-remote/link/src/main/java/org/sopt/remote/link/response/ResponsePatchTitleDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.remote.link.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class ResponsePatchTitleDto( 8 | @SerialName("updatedTitle") 9 | val updatedTitle: String, 10 | ) 11 | -------------------------------------------------------------------------------- /data-remote/timer/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data-remote/timer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.timerremote" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.data.timer) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data-remote/timer/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data-remote/timer/consumer-rules.pro -------------------------------------------------------------------------------- /data-remote/timer/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data-remote/timer/src/main/java/org/sopt/timerremote/di/ApiModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timerremote.di 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.network.di.AuthLinkMindRetrofit 8 | import org.sopt.timerremote.api.TimerService 9 | import retrofit2.Retrofit 10 | import javax.inject.Singleton 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | object ApiModule { 15 | @Provides 16 | @Singleton 17 | fun provideTimerService(@AuthLinkMindRetrofit retrofit: Retrofit): TimerService = 18 | retrofit.create(TimerService::class.java) 19 | } 20 | -------------------------------------------------------------------------------- /data-remote/timer/src/main/java/org/sopt/timerremote/di/DataSourceModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timerremote.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.timer.source.remote.TimerRemoteDataSource 8 | import org.sopt.timerremote.source.TimerRemoteDataSourceImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class DataSourceModule { 14 | @Binds 15 | @Singleton 16 | abstract fun bindsTimerRemoteDataSource(timerRemoteDataSource: TimerRemoteDataSourceImpl): TimerRemoteDataSource 17 | } 18 | -------------------------------------------------------------------------------- /data-remote/timer/src/main/java/org/sopt/timerremote/model/request/RequestPatchTimerDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timerremote.model.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.model.timer.TimerData 6 | 7 | @Serializable 8 | data class RequestPatchTimerDto( 9 | @SerialName("remindTime") 10 | val remindTime: String, 11 | @SerialName("remindDates") 12 | val remindDates: List, 13 | ) 14 | 15 | fun TimerData.toPatchDto() = RequestPatchTimerDto( 16 | remindTime = this.remindTime, 17 | remindDates = this.remindDates, 18 | ) 19 | -------------------------------------------------------------------------------- /data-remote/timer/src/main/java/org/sopt/timerremote/model/request/RequestPostTimerDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timerremote.model.request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.model.timer.TimerData 6 | 7 | @Serializable 8 | data class RequestPostTimerDto( 9 | @SerialName("categoryId") 10 | val categoryId: Long?, 11 | @SerialName("remindTime") 12 | val remindTime: String, 13 | @SerialName("remindDates") 14 | val remindDates: List, 15 | ) 16 | 17 | fun TimerData.toPostDto() = RequestPostTimerDto( 18 | categoryId = this.categoryId, 19 | remindTime = this.remindTime, 20 | remindDates = this.remindDates, 21 | ) 22 | -------------------------------------------------------------------------------- /data-remote/timer/src/main/java/org/sopt/timerremote/model/response/ResponseGetTimerDto.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timerremote.model.response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class ResponseGetTimerDto( 8 | @SerialName("categoryName") 9 | val categoryName: String, 10 | @SerialName("remindTime") 11 | val remindTime: String, 12 | @SerialName("remindDates") 13 | val remindDates: List, 14 | ) 15 | -------------------------------------------------------------------------------- /data-remote/user/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data-remote/user/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.remote.user" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.data.user) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data-remote/user/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data-remote/user/consumer-rules.pro -------------------------------------------------------------------------------- /data-remote/user/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data-remote/user/src/main/java/di/UserDataSourceModule.kt: -------------------------------------------------------------------------------- 1 | package di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import datasource.RemoteUserDataSourceImpl 8 | import org.sopt.user.source.RemoteUserDataSource 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class UserDataSourceModule { 14 | @Singleton 15 | @Binds 16 | abstract fun bindRemoteLectureProviderDatasource( 17 | remoteUserDataSource: RemoteUserDataSourceImpl, 18 | ): RemoteUserDataSource 19 | } 20 | -------------------------------------------------------------------------------- /data-remote/user/src/main/java/di/UserServiceModule.kt: -------------------------------------------------------------------------------- 1 | package di 2 | 3 | import api.UserService 4 | import dagger.Module 5 | import dagger.Provides 6 | import dagger.hilt.InstallIn 7 | import dagger.hilt.components.SingletonComponent 8 | import org.sopt.network.di.AuthLinkMindRetrofit 9 | import retrofit2.Retrofit 10 | import javax.inject.Singleton 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | object UserServiceModule { 15 | 16 | @Singleton 17 | @Provides 18 | fun provideUserService(@AuthLinkMindRetrofit retrofit: Retrofit): UserService = 19 | retrofit.create(UserService::class.java) 20 | } 21 | -------------------------------------------------------------------------------- /data-remote/user/src/main/java/request/RequestIsAllowedDto.kt: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class RequestIsAllowedDto( 8 | @SerialName("allowedPush") val allowedPush: Boolean, 9 | ) 10 | -------------------------------------------------------------------------------- /data-remote/user/src/main/java/response/ResponseGetUserSettingDto.kt: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.sopt.model.user.SettingPageData 6 | 7 | @Serializable 8 | data class ResponseGetUserSettingDto( 9 | @SerialName("nickname") 10 | val nickname: String, 11 | @SerialName("fcmIsAllowed") 12 | val fcmIsAllowed: Boolean, 13 | ) 14 | 15 | fun ResponseGetUserSettingDto.toCoreModel(): SettingPageData { 16 | return SettingPageData( 17 | nickname = nickname, 18 | fcmIsAllowed = fcmIsAllowed, 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /data-remote/user/src/main/java/response/ResponseIsAllowedDto.kt: -------------------------------------------------------------------------------- 1 | package response 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | class ResponseIsAllowedDto( 8 | @SerialName("isAllowed") 9 | val isFcmAllowed: Boolean, 10 | ) 11 | -------------------------------------------------------------------------------- /data/category/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data/category/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.data.category" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.domain.category) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data/category/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data/category/consumer-rules.pro -------------------------------------------------------------------------------- /data/category/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/category/src/main/java/org/sopt/data/category/datasource/RemoteCategoryDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.data.category.datasource 2 | 3 | import org.sopt.model.category.CategoryDuplicate 4 | import org.sopt.model.category.CategoryLinkList 5 | import org.sopt.model.category.CategoryList 6 | 7 | interface RemoteCategoryDataSource { 8 | suspend fun getCategoryAll(): CategoryList 9 | 10 | suspend fun postAddCategoryTitle(categoryTitle: String?): Int 11 | 12 | suspend fun deleteCategory(deleteCategoryList: Long) 13 | 14 | suspend fun getCategoryDuplicate(title: String): CategoryDuplicate 15 | 16 | suspend fun getCategoryLink(filter: String?, categoryId: Long?): CategoryLinkList 17 | 18 | suspend fun patchCategoryPriority(categoryId: Long, newPriority: Int) 19 | 20 | suspend fun patchCategoryEditTitle(categoryId: Long, newTitle: String) 21 | } 22 | -------------------------------------------------------------------------------- /data/category/src/main/java/org/sopt/data/category/datasource/RemoteSearchDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.data.category.datasource 2 | 3 | import org.sopt.model.category.SearchResultList 4 | 5 | interface RemoteSearchDataSource { 6 | suspend fun getSearchResult(query: String): SearchResultList 7 | } 8 | -------------------------------------------------------------------------------- /data/category/src/main/java/org/sopt/data/category/repository/SearchRepoImpl.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.data.category.repository 2 | 3 | import org.sopt.data.category.datasource.RemoteSearchDataSource 4 | import org.sopt.domain.category.category.repository.SearchRepository 5 | import org.sopt.model.category.SearchResultList 6 | import javax.inject.Inject 7 | 8 | class SearchRepoImpl @Inject constructor( 9 | private val remoteSearchDataSource: RemoteSearchDataSource, 10 | ) : SearchRepository { 11 | override suspend fun getSearchResult(query: String): Result = 12 | runCatching { remoteSearchDataSource.getSearchResult(query) } 13 | } 14 | -------------------------------------------------------------------------------- /data/home/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data/home/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.data.home" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.domain.home) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data/home/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data/home/consumer-rules.pro -------------------------------------------------------------------------------- /data/home/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/home/src/main/java/org/sopt/home/datasource/RemoteHomeDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.datasource 2 | 3 | import org.sopt.model.home.MainPageData 4 | import org.sopt.model.home.RecentSavedLink 5 | import org.sopt.model.home.RecommendLink 6 | import org.sopt.model.home.WeekBestLink 7 | 8 | interface RemoteHomeDataSource { 9 | suspend fun getMainPageUserClip(): MainPageData 10 | suspend fun getRecommendSite(): List 11 | suspend fun getWeekBestLink(): List 12 | suspend fun getRecentSavedLink(): List 13 | } 14 | -------------------------------------------------------------------------------- /data/home/src/main/java/org/sopt/home/datasource/RemotePopupDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.datasource 2 | 3 | import org.sopt.model.home.PopupInfo 4 | import org.sopt.model.home.PopupInvisible 5 | 6 | interface RemotePopupDataSource { 7 | suspend fun patchPopupInvisible(popupId: Long, hideDate: Long): PopupInvisible 8 | suspend fun getPopupInfo(): List 9 | } 10 | -------------------------------------------------------------------------------- /data/home/src/main/java/org/sopt/home/di/RepositoryModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.home.repository.HomeRepoImpl 8 | import org.sopt.home.repository.HomeRepository 9 | import org.sopt.home.repository.PopupRepoImpl 10 | import org.sopt.home.repository.PopupRepository 11 | import javax.inject.Singleton 12 | 13 | @Module 14 | @InstallIn(SingletonComponent::class) 15 | abstract class RepositoryModule { 16 | @Singleton 17 | @Binds 18 | abstract fun bindHomeRepository( 19 | homeRepoImpl: HomeRepoImpl, 20 | ): HomeRepository 21 | 22 | @Singleton 23 | @Binds 24 | abstract fun bindPopupRepository( 25 | popupRepoImpl: PopupRepoImpl, 26 | ): PopupRepository 27 | } 28 | -------------------------------------------------------------------------------- /data/home/src/main/java/org/sopt/home/repository/PopupRepoImpl.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.repository 2 | 3 | import org.sopt.home.datasource.RemotePopupDataSource 4 | import org.sopt.model.home.PopupInfo 5 | import org.sopt.model.home.PopupInvisible 6 | import javax.inject.Inject 7 | 8 | class PopupRepoImpl @Inject constructor( 9 | private val remotePopupDataSource: RemotePopupDataSource, 10 | ) : PopupRepository { 11 | override suspend fun patchPopupInvisible(popupId: Long, hideDate: Long): Result = 12 | runCatching { remotePopupDataSource.patchPopupInvisible(popupId, hideDate) } 13 | 14 | override suspend fun getPopupInfo(): Result> = 15 | runCatching { remotePopupDataSource.getPopupInfo() } 16 | } 17 | -------------------------------------------------------------------------------- /data/link/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data/link/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | 3 | plugins { 4 | alias(libs.plugins.linkmind.plugin.data) 5 | alias(libs.plugins.kotlin.serialization) 6 | } 7 | 8 | android { 9 | namespace = "org.sopt.data.link" 10 | } 11 | 12 | dependencies { 13 | implementation(projects.core.network) 14 | implementation(projects.domain.link) 15 | implementation(libs.retrofit.kotlin.serialization) 16 | } 17 | -------------------------------------------------------------------------------- /data/link/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data/link/consumer-rules.pro -------------------------------------------------------------------------------- /data/link/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/link/src/main/java/org/sopt/data/link/datasource/RemoteLinkDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.data.link.datasource 2 | 3 | interface RemoteLinkDataSource { 4 | suspend fun postSaveLink(linkUrl: String, categoryId: Long?): Int 5 | suspend fun deleteLink(toastId: Long): Int 6 | suspend fun patchReadLink(toastId: Long, isRead: Boolean): Boolean 7 | suspend fun patchLinkTitle(toastId: Long, title: String): String 8 | suspend fun patchLinkCategory(toastId: Long, categoryId: Long): Long 9 | } 10 | -------------------------------------------------------------------------------- /data/link/src/main/java/org/sopt/data/link/di/RepositoryModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.data.link.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.data.link.repository.LinkRepoImpl 8 | import org.sopt.domain.link.repository.LinkRepository 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class RepositoryModule { 14 | @Singleton 15 | @Binds 16 | abstract fun bindLinkRepository( 17 | linkRepoImpl: LinkRepoImpl, 18 | ): LinkRepository 19 | } 20 | -------------------------------------------------------------------------------- /data/oauthdata/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data/oauthdata/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.oauthdata" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.domain.oauthdomain) 13 | implementation(libs.kakao.login) 14 | } 15 | -------------------------------------------------------------------------------- /data/oauthdata/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data/oauthdata/consumer-rules.pro -------------------------------------------------------------------------------- /data/oauthdata/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/oauthdata/src/main/java/org/sopt/oauthdata/di/ClientModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.oauthdata.di 2 | 3 | import com.kakao.sdk.user.UserApiClient 4 | import dagger.Module 5 | import dagger.Provides 6 | import dagger.hilt.InstallIn 7 | import dagger.hilt.components.SingletonComponent 8 | import javax.inject.Singleton 9 | 10 | @Module 11 | @InstallIn(SingletonComponent::class) 12 | object ClientModule { 13 | @Provides 14 | @Singleton 15 | fun provideKakaoClient(): UserApiClient = UserApiClient.instance 16 | } 17 | -------------------------------------------------------------------------------- /data/oauthdata/src/main/java/org/sopt/oauthdata/di/KakaoAuthModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.oauthdata.di 2 | 3 | import dagger.Module 4 | import dagger.Provides 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.android.components.ActivityComponent 7 | import dagger.hilt.android.scopes.ActivityScoped 8 | import org.sopt.oauthdata.interactor.KakaoAuthInteractor 9 | import org.sopt.oauthdomain.interactor.OAuthInteractor 10 | 11 | @Module 12 | @InstallIn(ActivityComponent::class) 13 | object KakaoAuthModule { 14 | @Provides 15 | @ActivityScoped 16 | fun provideKakaoAuthRepository( 17 | kakaoAuthInteractor: KakaoAuthInteractor, 18 | ): OAuthInteractor = kakaoAuthInteractor 19 | } 20 | -------------------------------------------------------------------------------- /data/timer/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data/timer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.timerdata" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.domain.timer) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data/timer/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data/timer/consumer-rules.pro -------------------------------------------------------------------------------- /data/timer/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/timer/src/main/java/org/sopt/timer/di/RepositoryModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.timer.repository.TimerRepository 8 | import org.sopt.timer.repository.TimerRepositoryImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class RepositoryModule { 14 | @Binds 15 | @Singleton 16 | abstract fun bindsTimerRepository(timerRepository: TimerRepositoryImpl): TimerRepository 17 | } 18 | -------------------------------------------------------------------------------- /data/timer/src/main/java/org/sopt/timer/source/local/TimerLocalDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.source.local 2 | 3 | interface TimerLocalDataSource { 4 | // TODO 5 | } 6 | -------------------------------------------------------------------------------- /data/timer/src/main/java/org/sopt/timer/source/remote/TimerRemoteDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.source.remote 2 | 3 | import org.sopt.model.timer.Timer 4 | import org.sopt.model.timer.TimerData 5 | import org.sopt.network.model.response.base.BaseResponse 6 | 7 | interface TimerRemoteDataSource { 8 | suspend fun getTimerMain(): Pair, List>? 9 | 10 | suspend fun postTimer(timerData: TimerData): BaseResponse 11 | suspend fun deleteTimer(timerId: Int): BaseResponse 12 | 13 | suspend fun patchTimer(timerId: Int, timerData: TimerData): BaseResponse 14 | suspend fun patchAlarm(timerId: Int): BaseResponse 15 | } 16 | -------------------------------------------------------------------------------- /data/user/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /data/user/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.data) 4 | alias(libs.plugins.kotlin.serialization) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.user" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.network) 13 | implementation(projects.domain.user) 14 | implementation(libs.retrofit.kotlin.serialization) 15 | } 16 | -------------------------------------------------------------------------------- /data/user/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/data/user/consumer-rules.pro -------------------------------------------------------------------------------- /data/user/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/user/src/main/java/org/sopt/user/di/RepositoryModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.user.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.user.repository.UserRepository 8 | import org.sopt.user.repository.UserRepositoryImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | @InstallIn(SingletonComponent::class) 13 | abstract class RepositoryModule { 14 | @Singleton 15 | @Binds 16 | abstract fun bindUserRepository(userRepository: UserRepositoryImpl): UserRepository 17 | } 18 | -------------------------------------------------------------------------------- /data/user/src/main/java/org/sopt/user/source/RemoteUserDataSource.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.user.source 2 | 3 | import org.sopt.model.user.MyPageData 4 | import org.sopt.model.user.SettingPageData 5 | 6 | interface RemoteUserDataSource { 7 | suspend fun getMyPage(): MyPageData 8 | suspend fun getSetting(): SettingPageData 9 | suspend fun patchAllowedPush(allowedPush: Boolean): Boolean 10 | } 11 | -------------------------------------------------------------------------------- /domain/category/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /domain/category/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.java.library) 4 | } 5 | dependencies { 6 | implementation(projects.core.model) 7 | implementation(libs.kotlinx.coroutines.core) 8 | implementation(libs.hilt.core) 9 | } 10 | -------------------------------------------------------------------------------- /domain/category/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/domain/category/consumer-rules.pro -------------------------------------------------------------------------------- /domain/category/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/repository/SearchRepository.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.repository 2 | 3 | import org.sopt.model.category.SearchResultList 4 | 5 | interface SearchRepository { 6 | suspend fun getSearchResult(query: String): Result 7 | } 8 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/usecase/DeleteCategoryUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.usecase 2 | 3 | import org.sopt.domain.category.category.repository.CategoryRepository 4 | import javax.inject.Inject 5 | 6 | class DeleteCategoryUseCase @Inject constructor( 7 | private val categoryRepository: CategoryRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = categoryRepository.deleteCategory( 10 | deleteCategoryList = param.deleteCategoryList, 11 | ) 12 | data class Param( 13 | val deleteCategoryList: Long, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/usecase/GetCategoryAllUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.usecase 2 | 3 | import org.sopt.domain.category.category.repository.CategoryRepository 4 | import org.sopt.model.category.CategoryList 5 | import javax.inject.Inject 6 | 7 | class GetCategoryAllUseCase @Inject constructor( 8 | private val categoryRepository: CategoryRepository, 9 | ) { 10 | suspend operator fun invoke(): Result = categoryRepository.getCategoryAll() 11 | } 12 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/usecase/GetCategoryDuplicateUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.usecase 2 | 3 | import org.sopt.domain.category.category.repository.CategoryRepository 4 | import org.sopt.model.category.CategoryDuplicate 5 | import javax.inject.Inject 6 | 7 | class GetCategoryDuplicateUseCase @Inject constructor( 8 | private val categoryRepository: CategoryRepository, 9 | ) { 10 | suspend operator fun invoke(param: Param): Result = categoryRepository.getCategoryDuplicate( 11 | title = param.title, 12 | ) 13 | data class Param( 14 | val title: String, 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/usecase/GetCategoryLinkUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.usecase 2 | 3 | import org.sopt.domain.category.category.repository.CategoryRepository 4 | import org.sopt.model.category.CategoryLinkList 5 | import javax.inject.Inject 6 | 7 | class GetCategoryLinkUseCase @Inject constructor( 8 | private val categoryRepository: CategoryRepository, 9 | ) { 10 | suspend operator fun invoke(param: Param): Result = categoryRepository.getCategoryLink( 11 | filter = param.filter, 12 | categoryId = param.categoryId, 13 | ) 14 | 15 | data class Param( 16 | val filter: String?, 17 | val categoryId: Long?, 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/usecase/GetSearchResultUserCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.usecase 2 | 3 | import org.sopt.domain.category.category.repository.SearchRepository 4 | import org.sopt.model.category.SearchResultList 5 | import javax.inject.Inject 6 | 7 | class GetSearchResultUserCase @Inject constructor( 8 | private val searchRepository: SearchRepository, 9 | ) { 10 | suspend operator fun invoke(query: String): Result = searchRepository.getSearchResult( 11 | query = query, 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/usecase/PatchCategoryEditPriorityUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.usecase 2 | 3 | import org.sopt.domain.category.category.repository.CategoryRepository 4 | import javax.inject.Inject 5 | 6 | class PatchCategoryEditPriorityUseCase @Inject constructor( 7 | private val categoryRepository: CategoryRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = categoryRepository.patchCategoryEditPriority( 10 | categoryId = param.categoryId, 11 | newPriority = param.newPriority, 12 | ) 13 | 14 | data class Param( 15 | val categoryId: Long, 16 | val newPriority: Int, 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/usecase/PatchCategoryEditTitleUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.usecase 2 | 3 | import org.sopt.domain.category.category.repository.CategoryRepository 4 | import javax.inject.Inject 5 | 6 | class PatchCategoryEditTitleUseCase @Inject constructor( 7 | private val categoryRepository: CategoryRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = categoryRepository.patchCategoryEditTitle( 10 | categoryId = param.categoryId, 11 | newTitle = param.newTitle, 12 | ) 13 | 14 | data class Param( 15 | val categoryId: Long, 16 | val newTitle: String, 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /domain/category/src/main/java/org/sopt/domain/category/category/usecase/PostAddCategoryTitleUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.category.category.usecase 2 | 3 | import org.sopt.domain.category.category.repository.CategoryRepository 4 | import javax.inject.Inject 5 | 6 | class PostAddCategoryTitleUseCase @Inject constructor( 7 | private val categoryRepository: CategoryRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = categoryRepository.postAddCategory( 10 | categoryTitle = param.categoryTitle, 11 | ) 12 | data class Param( 13 | val categoryTitle: String, 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /domain/home/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /domain/home/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.java.library) 4 | } 5 | dependencies { 6 | implementation(projects.core.model) 7 | implementation(libs.kotlinx.coroutines.core) 8 | implementation(libs.hilt.core) 9 | } 10 | -------------------------------------------------------------------------------- /domain/home/src/main/java/org/sopt/home/repository/HomeRepository.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.repository 2 | 3 | import org.sopt.model.home.MainPageData 4 | import org.sopt.model.home.RecentSavedLink 5 | import org.sopt.model.home.RecommendLink 6 | import org.sopt.model.home.WeekBestLink 7 | 8 | interface HomeRepository { 9 | suspend fun getMainPageUserClip(): Result 10 | suspend fun getRecommendSite(): Result> 11 | suspend fun getWeekBestLink(): Result> 12 | suspend fun getRecentSavedLink(): Result> 13 | } 14 | -------------------------------------------------------------------------------- /domain/home/src/main/java/org/sopt/home/repository/PopupRepository.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.repository 2 | 3 | import org.sopt.model.home.PopupInfo 4 | import org.sopt.model.home.PopupInvisible 5 | 6 | interface PopupRepository { 7 | suspend fun patchPopupInvisible(popupId: Long, hideDate: Long): Result 8 | suspend fun getPopupInfo(): Result> 9 | } 10 | -------------------------------------------------------------------------------- /domain/home/src/main/java/org/sopt/home/usecase/GetMainPageUserClip.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.usecase 2 | 3 | import org.sopt.home.repository.HomeRepository 4 | import org.sopt.model.home.MainPageData 5 | import javax.inject.Inject 6 | 7 | class GetMainPageUserClip @Inject constructor( 8 | private val homeRepository: HomeRepository, 9 | ) { 10 | suspend operator fun invoke(): Result = homeRepository.getMainPageUserClip() 11 | } 12 | -------------------------------------------------------------------------------- /domain/home/src/main/java/org/sopt/home/usecase/GetPopupInfo.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.usecase 2 | 3 | import org.sopt.home.repository.PopupRepository 4 | import org.sopt.model.home.PopupInfo 5 | import javax.inject.Inject 6 | 7 | class GetPopupInfo @Inject constructor( 8 | private val popupRepository: PopupRepository, 9 | ) { 10 | suspend operator fun invoke(): Result> = popupRepository.getPopupInfo() 11 | } 12 | -------------------------------------------------------------------------------- /domain/home/src/main/java/org/sopt/home/usecase/GetRecentSavedLink.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.usecase 2 | 3 | import org.sopt.home.repository.HomeRepository 4 | import org.sopt.model.home.RecentSavedLink 5 | import javax.inject.Inject 6 | 7 | class GetRecentSavedLink @Inject constructor( 8 | private val homeRepository: HomeRepository, 9 | ) { 10 | suspend operator fun invoke(): Result> = homeRepository.getRecentSavedLink() 11 | } 12 | -------------------------------------------------------------------------------- /domain/home/src/main/java/org/sopt/home/usecase/GetRecommendSite.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.usecase 2 | 3 | import org.sopt.home.repository.HomeRepository 4 | import org.sopt.model.home.RecommendLink 5 | import javax.inject.Inject 6 | 7 | class GetRecommendSite @Inject constructor( 8 | private val homeRepository: HomeRepository, 9 | ) { 10 | suspend operator fun invoke(): Result> = homeRepository.getRecommendSite() 11 | } 12 | -------------------------------------------------------------------------------- /domain/home/src/main/java/org/sopt/home/usecase/GetWeekBestLink.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.usecase 2 | 3 | import org.sopt.home.repository.HomeRepository 4 | import org.sopt.model.home.WeekBestLink 5 | import javax.inject.Inject 6 | 7 | class GetWeekBestLink @Inject constructor( 8 | private val homeRepository: HomeRepository, 9 | ) { 10 | suspend operator fun invoke(): Result> = homeRepository.getWeekBestLink() 11 | } 12 | -------------------------------------------------------------------------------- /domain/home/src/main/java/org/sopt/home/usecase/PatchPopupInvisible.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.usecase 2 | 3 | import org.sopt.home.repository.PopupRepository 4 | import org.sopt.model.home.PopupInvisible 5 | import javax.inject.Inject 6 | 7 | class PatchPopupInvisible @Inject constructor( 8 | private val popupRepository: PopupRepository, 9 | ) { 10 | suspend operator fun invoke(popupId: Long, hideDate: Long): Result = 11 | popupRepository.patchPopupInvisible(popupId, hideDate) 12 | } 13 | -------------------------------------------------------------------------------- /domain/link/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /domain/link/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.java.library) 4 | } 5 | dependencies { 6 | implementation(projects.core.model) 7 | implementation(libs.kotlinx.coroutines.core) 8 | implementation(libs.hilt.core) 9 | } 10 | -------------------------------------------------------------------------------- /domain/link/src/main/java/org/sopt/domain/link/repository/LinkRepository.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.link.repository 2 | 3 | interface LinkRepository { 4 | suspend fun postSaveLink(linkUrl: String, categoryId: Long?): Result 5 | suspend fun deleteLink(toastId: Long): Result 6 | suspend fun patchReadLink(toastId: Long, isRead: Boolean): Result 7 | suspend fun patchLinkTitle(toastId: Long, title: String): Result 8 | suspend fun patchToastCategory(toastId: Long, categoryId: Long): Result 9 | } 10 | -------------------------------------------------------------------------------- /domain/link/src/main/java/org/sopt/domain/link/usecase/DeleteLinkUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.link.usecase 2 | 3 | import org.sopt.domain.link.repository.LinkRepository 4 | import javax.inject.Inject 5 | 6 | class DeleteLinkUseCase @Inject constructor( 7 | private val linkRepository: LinkRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = linkRepository.deleteLink( 10 | toastId = param.toastId, 11 | ) 12 | 13 | data class Param( 14 | val toastId: Long, 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /domain/link/src/main/java/org/sopt/domain/link/usecase/PatchLinkCategoryUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.link.usecase 2 | 3 | import org.sopt.domain.link.repository.LinkRepository 4 | import javax.inject.Inject 5 | 6 | class PatchLinkCategoryUseCase @Inject constructor( 7 | private val linkRepository: LinkRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = linkRepository.patchToastCategory( 10 | toastId = param.toastId, 11 | categoryId = param.categoryId, 12 | ) 13 | 14 | data class Param( 15 | val toastId: Long, 16 | val categoryId: Long, 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /domain/link/src/main/java/org/sopt/domain/link/usecase/PatchLinkTitleUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.link.usecase 2 | 3 | import org.sopt.domain.link.repository.LinkRepository 4 | import javax.inject.Inject 5 | 6 | class PatchLinkTitleUseCase @Inject constructor( 7 | private val linkRepository: LinkRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = linkRepository.patchLinkTitle( 10 | toastId = param.toastId, 11 | title = param.title, 12 | ) 13 | 14 | data class Param( 15 | val toastId: Long, 16 | val title: String, 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /domain/link/src/main/java/org/sopt/domain/link/usecase/PatchReadLinkUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.link.usecase 2 | 3 | import org.sopt.domain.link.repository.LinkRepository 4 | import javax.inject.Inject 5 | 6 | class PatchReadLinkUseCase @Inject constructor( 7 | private val linkRepository: LinkRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = linkRepository.patchReadLink( 10 | toastId = param.toastId, 11 | isRead = param.isRead, 12 | ) 13 | 14 | data class Param( 15 | val toastId: Long, 16 | val isRead: Boolean, 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /domain/link/src/main/java/org/sopt/domain/link/usecase/PostSaveLinkUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.domain.link.usecase 2 | 3 | import org.sopt.domain.link.repository.LinkRepository 4 | import javax.inject.Inject 5 | 6 | class PostSaveLinkUseCase @Inject constructor( 7 | private val linkRepository: LinkRepository, 8 | ) { 9 | suspend operator fun invoke(param: Param): Result = linkRepository.postSaveLink( 10 | linkUrl = param.linkUrl, 11 | categoryId = param.categoryId, 12 | ) 13 | 14 | data class Param( 15 | val linkUrl: String, 16 | val categoryId: Long?, 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /domain/oauthdomain/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /domain/oauthdomain/build.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 3 | plugins { 4 | alias(libs.plugins.linkmind.java.library) 5 | } 6 | dependencies { 7 | implementation(projects.core.model) 8 | implementation(libs.kotlinx.coroutines.core) 9 | implementation(libs.hilt.core) 10 | } 11 | -------------------------------------------------------------------------------- /domain/oauthdomain/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/domain/oauthdomain/consumer-rules.pro -------------------------------------------------------------------------------- /domain/oauthdomain/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /domain/oauthdomain/src/main/java/org/sopt/oauthdomain/entity/KakaoToken.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.oauthdomain.entity 2 | 3 | data class KakaoToken( 4 | val accessToken: String, 5 | val refreshToken: String, 6 | ) 7 | -------------------------------------------------------------------------------- /domain/oauthdomain/src/main/java/org/sopt/oauthdomain/interactor/OAuthInteractor.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.oauthdomain.interactor 2 | 3 | import org.sopt.oauthdomain.entity.KakaoToken 4 | 5 | interface OAuthInteractor { 6 | suspend fun loginByKakao(): Result 7 | fun logout() 8 | fun withdraw() 9 | } 10 | -------------------------------------------------------------------------------- /domain/timer/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /domain/timer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.java.library) 4 | } 5 | dependencies { 6 | implementation(projects.core.model) 7 | implementation(libs.kotlinx.coroutines.core) 8 | implementation(libs.hilt.core) 9 | } 10 | -------------------------------------------------------------------------------- /domain/timer/src/main/java/org/sopt/timer/repository/TimerRepository.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.repository 2 | 3 | import org.sopt.model.timer.Timer 4 | import org.sopt.model.timer.TimerData 5 | 6 | interface TimerRepository { 7 | suspend fun getTimerMain(): Result, List>?> 8 | 9 | suspend fun postTimer(timerData: TimerData): Result 10 | 11 | suspend fun deleteTimer(timerId: Int): Result 12 | 13 | suspend fun patchTimer(timerId: Int, timerData: TimerData): Result 14 | 15 | suspend fun patchAlarm(timerId: Int): Result 16 | } 17 | -------------------------------------------------------------------------------- /domain/timer/src/main/java/org/sopt/timer/usecase/DeleteTimerUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.usecase 2 | 3 | import org.sopt.timer.repository.TimerRepository 4 | import javax.inject.Inject 5 | 6 | class DeleteTimerUseCase @Inject constructor( 7 | private val timerRepository: TimerRepository, 8 | ) { 9 | suspend operator fun invoke(timerId: Int) = timerRepository.deleteTimer(timerId) 10 | } 11 | -------------------------------------------------------------------------------- /domain/timer/src/main/java/org/sopt/timer/usecase/FormatRepeatListToIntList.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.usecase 2 | 3 | import org.sopt.model.timer.Repeat 4 | import javax.inject.Inject 5 | 6 | class FormatRepeatListToIntList @Inject constructor() { 7 | operator fun invoke(repeatList: List): List { 8 | val selectedDays = mutableSetOf() 9 | 10 | repeatList.forEachIndexed { index, repeat -> 11 | if (repeat.isSelected) { 12 | when (index) { 13 | 0 -> return (1..7).toList() 14 | 1 -> selectedDays.addAll(1..5) 15 | 2 -> selectedDays.addAll(listOf(6, 7)) 16 | else -> selectedDays.add(index - 2) 17 | } 18 | } 19 | } 20 | return selectedDays.sorted() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /domain/timer/src/main/java/org/sopt/timer/usecase/GetTimerMainUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.usecase 2 | 3 | import org.sopt.timer.repository.TimerRepository 4 | import javax.inject.Inject 5 | 6 | class GetTimerMainUseCase @Inject constructor( 7 | private val timerRepository: TimerRepository, 8 | ) { 9 | suspend operator fun invoke() = timerRepository.getTimerMain() 10 | } 11 | -------------------------------------------------------------------------------- /domain/timer/src/main/java/org/sopt/timer/usecase/PatchAlarmUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.usecase 2 | 3 | import org.sopt.timer.repository.TimerRepository 4 | import javax.inject.Inject 5 | 6 | class PatchAlarmUseCase @Inject constructor( 7 | private val timerRepository: TimerRepository, 8 | ) { 9 | suspend operator fun invoke(timerId: Int) = timerRepository.patchAlarm(timerId) 10 | } 11 | -------------------------------------------------------------------------------- /domain/timer/src/main/java/org/sopt/timer/usecase/PatchTimerUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.usecase 2 | 3 | import org.sopt.model.timer.TimerData 4 | import org.sopt.timer.repository.TimerRepository 5 | import javax.inject.Inject 6 | 7 | class PatchTimerUseCase @Inject constructor( 8 | private val timerRepository: TimerRepository, 9 | ) { 10 | suspend operator fun invoke(timerId: Int, time: String, days: List) = 11 | timerRepository.patchTimer(timerId, TimerData(0, time, days)) 12 | } 13 | -------------------------------------------------------------------------------- /domain/timer/src/main/java/org/sopt/timer/usecase/PostTimerUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.usecase 2 | 3 | import org.sopt.model.timer.TimerData 4 | import org.sopt.timer.repository.TimerRepository 5 | import javax.inject.Inject 6 | 7 | class PostTimerUseCase @Inject constructor( 8 | private val timerRepository: TimerRepository, 9 | ) { 10 | suspend operator fun invoke(categoryId: Long?, time: String, days: List) = 11 | timerRepository.postTimer(TimerData(categoryId, time, days)) 12 | } 13 | -------------------------------------------------------------------------------- /domain/user/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /domain/user/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.java.library) 4 | } 5 | dependencies { 6 | implementation(projects.core.model) 7 | implementation(libs.kotlinx.coroutines.core) 8 | implementation(libs.hilt.core) 9 | } 10 | -------------------------------------------------------------------------------- /domain/user/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/domain/user/consumer-rules.pro -------------------------------------------------------------------------------- /domain/user/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /domain/user/src/main/java/org/sopt/user/repository/UserRepository.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.user.repository 2 | 3 | import org.sopt.model.user.MyPageData 4 | import org.sopt.model.user.SettingPageData 5 | 6 | interface UserRepository { 7 | suspend fun getUserMyPage(): Result 8 | 9 | suspend fun getUserSetting(): Result 10 | 11 | suspend fun patchPush(allowedPush: Boolean): Result 12 | } 13 | -------------------------------------------------------------------------------- /domain/user/src/main/java/org/sopt/user/usecase/GetUserMyPageUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.user.usecase 2 | 3 | import org.sopt.user.repository.UserRepository 4 | import javax.inject.Inject 5 | 6 | class GetUserMyPageUseCase @Inject constructor( 7 | private val userRepository: UserRepository, 8 | ) { 9 | suspend operator fun invoke() = userRepository.getUserMyPage() 10 | } 11 | -------------------------------------------------------------------------------- /domain/user/src/main/java/org/sopt/user/usecase/GetUserSettingUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.user.usecase 2 | 3 | import org.sopt.user.repository.UserRepository 4 | import javax.inject.Inject 5 | 6 | class GetUserSettingUseCase @Inject constructor( 7 | private val userRepository: UserRepository, 8 | ) { 9 | suspend operator fun invoke() = userRepository.getUserSetting() 10 | } 11 | -------------------------------------------------------------------------------- /domain/user/src/main/java/org/sopt/user/usecase/PatchPushUseCase.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.user.usecase 2 | 3 | import org.sopt.user.repository.UserRepository 4 | import javax.inject.Inject 5 | 6 | class PatchPushUseCase @Inject constructor( 7 | private val userRepository: UserRepository, 8 | ) { 9 | suspend operator fun invoke(allowedPush: Boolean) = userRepository.patchPush(allowedPush) 10 | } 11 | -------------------------------------------------------------------------------- /feature/clip/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/clip/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.clip" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(projects.domain.category) 16 | implementation(projects.domain.link) 17 | implementation(projects.core.datastore) 18 | implementation(libs.coil) 19 | } 20 | -------------------------------------------------------------------------------- /feature/clip/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/feature/clip/consumer-rules.pro -------------------------------------------------------------------------------- /feature/clip/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /feature/clip/src/main/java/org/sopt/clip/SelectedToggle.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.clip 2 | 3 | enum class SelectedToggle { 4 | ALL, READ, UNREAD 5 | } 6 | -------------------------------------------------------------------------------- /feature/clip/src/main/res/drawable/ic_back_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /feature/clip/src/main/res/drawable/ic_next_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 13 | 20 | 21 | -------------------------------------------------------------------------------- /feature/clip/src/main/res/drawable/shape_grey050_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /feature/clip/src/main/res/drawable/shape_grey050_fill_8_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /feature/clip/src/main/res/drawable/shape_parent_fill_rect.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /feature/clip/src/main/res/drawable/shape_white_fill_12_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /feature/clip/src/main/res/drawable/shape_white_fill_8_rect.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /feature/home/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/home/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.home" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(projects.domain.home) 16 | implementation(projects.domain.category) 17 | implementation(libs.coil) 18 | implementation(libs.jsoup) 19 | implementation(libs.orbit.core) 20 | implementation(libs.orbit.viewmodel) 21 | implementation(libs.google.play.app.update) 22 | implementation(projects.core.datastore) 23 | } 24 | -------------------------------------------------------------------------------- /feature/home/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/feature/home/consumer-rules.pro -------------------------------------------------------------------------------- /feature/home/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /feature/home/src/main/java/org/sopt/home/adapter/ItemDecoration.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.adapter 2 | 3 | import android.graphics.Rect 4 | import android.view.View 5 | import androidx.recyclerview.widget.RecyclerView 6 | 7 | class ItemDecoration( 8 | private val spanCount: Int, 9 | private val spacing: Int, 10 | ) : RecyclerView.ItemDecoration() { 11 | 12 | override fun getItemOffsets( 13 | outRect: Rect, 14 | view: View, 15 | parent: RecyclerView, 16 | state: RecyclerView.State, 17 | ) { 18 | val position = parent.getChildAdapterPosition(view) 19 | val column = position % spanCount 20 | 21 | outRect.left = column * spacing / spanCount 22 | outRect.right = spacing - (column + 1) * spacing / spanCount 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /feature/home/src/main/java/org/sopt/home/model/UpdatePriority.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.model 2 | 3 | enum class UpdatePriority { 4 | EMPTY, 5 | MINOR, 6 | MAJOR, 7 | CRITICAL, 8 | ; 9 | 10 | companion object { 11 | fun toUpdatePriority(value: Int): UpdatePriority { 12 | return when (value) { 13 | in 0..1 -> MINOR 14 | in 2..3 -> MAJOR 15 | in 4..5 -> CRITICAL 16 | else -> EMPTY 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /feature/home/src/main/java/org/sopt/home/viewholder/HomeWeekLinkViewHolder.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.home.viewholder 2 | 3 | import androidx.recyclerview.widget.RecyclerView 4 | import coil.load 5 | import org.sopt.home.databinding.ItemWeekLinkBinding 6 | import org.sopt.model.home.WeekBestLink 7 | 8 | class HomeWeekLinkViewHolder( 9 | private val binding: ItemWeekLinkBinding, 10 | private val onClickWeekLink: (WeekBestLink) -> Unit, 11 | ) : RecyclerView.ViewHolder(binding.root) { 12 | 13 | fun onBind(data: WeekBestLink?) { 14 | if (data == null) return 15 | 16 | with(binding) { 17 | binding.tvWeekLink.text = data.toastLink 18 | binding.tvWeekLinkTitle.text = data.toastTitle 19 | binding.ivWeekLink.load(data.toastImg) 20 | root.setOnClickListener { 21 | onClickWeekLink(data) 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /feature/home/src/main/res/drawable/shape_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /feature/home/src/main/res/navigation/nav_graph_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /feature/home/src/main/res/values/dimen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12dp 4 | 5 | 12dp 6 | 7 | -------------------------------------------------------------------------------- /feature/login/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/login/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.login" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(projects.core.datastore) 16 | implementation(projects.core.auth) 17 | implementation(projects.domain.oauthdomain) 18 | implementation(libs.viewpager.indicator) 19 | } 20 | -------------------------------------------------------------------------------- /feature/login/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/feature/login/consumer-rules.pro -------------------------------------------------------------------------------- /feature/login/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /feature/login/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /feature/login/src/main/java/org/sopt/login/onboarding/di/IntentModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.login.onboarding.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.common.intentprovider.IntentProvider 8 | import org.sopt.common.intentprovider.LOGIN 9 | import org.sopt.login.onboarding.intentprovider.IntentProviderImpl 10 | import javax.inject.Singleton 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | abstract class IntentModule { 15 | @Binds 16 | @Singleton 17 | @LOGIN 18 | abstract fun bindsIntentProvider(intentProvider: IntentProviderImpl): IntentProvider 19 | } 20 | -------------------------------------------------------------------------------- /feature/login/src/main/java/org/sopt/login/onboarding/intentprovider/IntentProviderImpl.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.login.onboarding.intentprovider 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import dagger.hilt.android.qualifiers.ApplicationContext 6 | import org.sopt.common.intentprovider.IntentProvider 7 | import org.sopt.login.onboarding.LoginActivity 8 | import javax.inject.Inject 9 | 10 | class IntentProviderImpl @Inject constructor( 11 | @ApplicationContext private val context: Context, 12 | ) : IntentProvider { 13 | override fun getIntent(): Intent = 14 | LoginActivity.newInstance(context) 15 | } 16 | -------------------------------------------------------------------------------- /feature/maincontainer/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/maincontainer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.maincontainer" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(projects.feature.home) 16 | implementation(projects.feature.clip) 17 | implementation(projects.feature.mypage) 18 | implementation(projects.feature.timer) 19 | implementation(projects.feature.search) 20 | implementation(projects.feature.savelink) 21 | implementation(projects.core.datastore) 22 | } 23 | -------------------------------------------------------------------------------- /feature/maincontainer/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/feature/maincontainer/consumer-rules.pro -------------------------------------------------------------------------------- /feature/maincontainer/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /feature/maincontainer/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /feature/maincontainer/src/main/java/org/sopt/maincontainer/MainContract.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.maincontainer 2 | 3 | data class MainState( 4 | val isBottomNavigationBarVisible: Boolean = true, 5 | val clipboard: String = "", 6 | val visibleBubbleMark: Boolean = false, 7 | ) 8 | 9 | sealed interface MainSideEffect { 10 | data object NavigateSaveLink : MainSideEffect 11 | } 12 | -------------------------------------------------------------------------------- /feature/maincontainer/src/main/java/org/sopt/maincontainer/di/IntentModule.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.maincontainer.di 2 | 3 | import dagger.Binds 4 | import dagger.Module 5 | import dagger.hilt.InstallIn 6 | import dagger.hilt.components.SingletonComponent 7 | import org.sopt.common.intentprovider.IntentProvider 8 | import org.sopt.common.intentprovider.MAIN 9 | import org.sopt.maincontainer.intentprovider.IntentProviderImpl 10 | import javax.inject.Singleton 11 | 12 | @Module 13 | @InstallIn(SingletonComponent::class) 14 | abstract class IntentModule { 15 | @Binds 16 | @Singleton 17 | @MAIN 18 | abstract fun bindsIntentProvider(intentProvider: IntentProviderImpl): IntentProvider 19 | } 20 | -------------------------------------------------------------------------------- /feature/maincontainer/src/main/java/org/sopt/maincontainer/intentprovider/IntentProviderImpl.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.maincontainer.intentprovider 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import dagger.hilt.android.qualifiers.ApplicationContext 6 | import org.sopt.common.intentprovider.IntentProvider 7 | import org.sopt.maincontainer.MainActivity 8 | import javax.inject.Inject 9 | 10 | class IntentProviderImpl @Inject constructor( 11 | @ApplicationContext private val context: Context, 12 | ) : IntentProvider { 13 | override fun getIntent(): Intent = 14 | MainActivity.newInstance(context) 15 | } 16 | -------------------------------------------------------------------------------- /feature/maincontainer/src/main/res/menu/menu_clip_tb.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /feature/maincontainer/src/main/res/navigation/nav_graph.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /feature/mypage/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/mypage/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.mypage" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(projects.core.datastore) 16 | implementation(projects.core.auth) 17 | implementation(projects.domain.user) 18 | implementation(libs.process.phoenix) 19 | implementation(libs.coil) 20 | } 21 | -------------------------------------------------------------------------------- /feature/mypage/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/feature/mypage/consumer-rules.pro -------------------------------------------------------------------------------- /feature/mypage/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /feature/savelink/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/savelink/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.savelink" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.domain.link) 13 | implementation(projects.domain.category) 14 | } 15 | -------------------------------------------------------------------------------- /feature/savelink/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/feature/savelink/consumer-rules.pro -------------------------------------------------------------------------------- /feature/savelink/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /feature/savelink/src/main/java/org/sopt/savelink/ui/model/Clip.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.savelink.ui.model 2 | 3 | import org.sopt.model.category.Category 4 | 5 | data class Clip( 6 | val categoryId: Long?, 7 | val categoryTitle: String, 8 | val toastNum: Long, 9 | var isSelected: Boolean, 10 | ) 11 | 12 | internal fun Category.toModel() = Clip( 13 | categoryId = categoryId, 14 | categoryTitle = categoryTitle ?: "", 15 | toastNum = toastNum, 16 | isSelected = false, 17 | ) 18 | -------------------------------------------------------------------------------- /feature/savelink/src/main/java/org/sopt/savelink/ui/savelink/LinkContract.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.savelink.ui.savelink 2 | 3 | import org.sopt.savelink.ui.model.Clip 4 | 5 | data class LinkState( 6 | val edittextLink: String = "", 7 | val categoryList: List = emptyList(), 8 | ) { 9 | fun checkEtvLink() = 10 | edittextLink.contains("http") 11 | } 12 | sealed interface LinkSideEffect { 13 | data object NavigateUp : LinkSideEffect 14 | data object NavigateSetLink : LinkSideEffect 15 | data object ShowDialog : LinkSideEffect 16 | } 17 | -------------------------------------------------------------------------------- /feature/savelink/src/main/java/org/sopt/savelink/ui/savelinksetclip/SetLinkContract.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.savelink.ui.savelinksetclip 2 | 3 | import org.sopt.savelink.ui.model.Clip 4 | 5 | data class SaveLinkSetClipState( 6 | val categoryList: List = emptyList(), 7 | val categoryId: Long? = 0, 8 | val url: String = "", 9 | val allClipCountNum: Long = 0, 10 | val duplicate: Boolean = false, 11 | val navHome: Boolean = false, 12 | ) 13 | sealed interface SaveLinkSetClipSideEffect { 14 | data object NavigateSaveLinkSetClip : SaveLinkSetClipSideEffect 15 | data object NavigateUp : SaveLinkSetClipSideEffect 16 | data object ShowBottomSheet : SaveLinkSetClipSideEffect 17 | data object ShowDialog : SaveLinkSetClipSideEffect 18 | data object ShowSnackBar : SaveLinkSetClipSideEffect 19 | data object ShowSnackBarError : SaveLinkSetClipSideEffect 20 | } 21 | -------------------------------------------------------------------------------- /feature/search/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/search/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.search" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(projects.domain.category) 16 | implementation(libs.orbit.core) 17 | implementation(libs.orbit.viewmodel) 18 | implementation(libs.coil) 19 | } 20 | -------------------------------------------------------------------------------- /feature/search/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.search" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(libs.coil) 16 | implementation(libs.jsoup) 17 | implementation(libs.orbit.core) 18 | implementation(libs.orbit.viewmodel) 19 | implementation(libs.google.play.core) 20 | implementation(projects.core.datastore) 21 | } 22 | -------------------------------------------------------------------------------- /feature/search/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /feature/search/src/main/java/org/sopt/search/SearchContract.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.search 2 | 3 | import org.sopt.model.category.Category 4 | import org.sopt.model.category.Toast 5 | 6 | data class SearchState( 7 | val searchedToasts: List = emptyList(), 8 | val searchedClip: List = emptyList(), 9 | val query: String = "", 10 | val isEmpty: Boolean = false, 11 | ) 12 | 13 | sealed interface SearchSideEffect { 14 | data class NavigateToClip(val id: Long, val title: String) : SearchSideEffect 15 | data class NavigateToWebView(val url: String, val id: Long, val isRead: Boolean) : SearchSideEffect 16 | } 17 | -------------------------------------------------------------------------------- /feature/search/src/main/java/org/sopt/search/util/TextStylerExt.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.search.util 2 | 3 | import android.graphics.Typeface 4 | import android.text.Spannable 5 | import android.text.SpannableString 6 | import android.text.style.StyleSpan 7 | 8 | fun applyBoldStyle(text: String?, searchQuery: String?): SpannableString { 9 | val spannable = SpannableString(text ?: "") 10 | 11 | if (!text.isNullOrEmpty() && !searchQuery.isNullOrEmpty()) { 12 | val startIndex = text.indexOf(searchQuery) 13 | if (startIndex != -1) { 14 | val endIndex = startIndex + searchQuery.length 15 | spannable.setSpan( 16 | StyleSpan(Typeface.BOLD), 17 | startIndex, 18 | endIndex, 19 | Spannable.SPAN_EXCLUSIVE_EXCLUSIVE, 20 | ) 21 | } 22 | } 23 | return spannable 24 | } 25 | -------------------------------------------------------------------------------- /feature/search/src/main/java/org/sopt/search/viewholder/ClipResultViewHolder.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.search.viewholder 2 | 3 | import androidx.recyclerview.widget.RecyclerView 4 | import org.sopt.model.category.Category 5 | import org.sopt.search.databinding.ItemSearchResultClipBinding 6 | import org.sopt.ui.view.onThrottleClick 7 | 8 | class ClipResultViewHolder(val binding: ItemSearchResultClipBinding) : 9 | RecyclerView.ViewHolder(binding.root) { 10 | 11 | fun onBind(clipResult: Category, onClick: (Category) -> Unit) { 12 | binding.tvClipTitle.text = clipResult.categoryTitle 13 | binding.tvClipAmount.text = clipResult.toastNum.toString() 14 | binding.root.onThrottleClick { 15 | onClick(clipResult) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /feature/search/src/main/res/navigation/nav_graph_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /feature/share/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/share/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.share" 9 | } 10 | 11 | dependencies { 12 | implementation(projects.core.datastore) 13 | implementation(projects.domain.link) 14 | implementation(projects.domain.category) 15 | implementation(libs.androidx.window) 16 | implementation(libs.process.phoenix) 17 | } 18 | -------------------------------------------------------------------------------- /feature/share/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/feature/share/consumer-rules.pro -------------------------------------------------------------------------------- /feature/share/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /feature/share/src/main/java/org/sopt/share/ShareContract.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.share 2 | 3 | import org.sopt.share.model.Clip 4 | 5 | data class ShareState( 6 | val categoryList: List = emptyList(), 7 | val categoryId: Long? = 0, 8 | val url: String = "", 9 | val allClipCountNum: Long = 0, 10 | ) 11 | 12 | sealed interface ShareSideEffect { 13 | 14 | sealed interface ShareActivitySideEffect : ShareSideEffect { 15 | data object DefinedUser : ShareActivitySideEffect 16 | 17 | data object UnDefinedUser : ShareActivitySideEffect 18 | } 19 | 20 | sealed interface ShareBottomSheetSideEffect : ShareSideEffect { 21 | data object SaveSuccess : ShareBottomSheetSideEffect 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /feature/share/src/main/java/org/sopt/share/model/Clip.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.share.model 2 | 3 | import org.sopt.model.category.Category 4 | 5 | data class Clip( 6 | val categoryId: Long?, 7 | val categoryTitle: String, 8 | val toastNum: Long, 9 | var isSelected: Boolean, 10 | ) 11 | 12 | internal fun Category.toModel() = Clip( 13 | categoryId = categoryId, 14 | categoryTitle = categoryTitle ?: "", 15 | toastNum = toastNum, 16 | isSelected = false, 17 | ) 18 | -------------------------------------------------------------------------------- /feature/share/src/main/res/layout/activity_share.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /feature/timer/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /feature/timer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed 2 | plugins { 3 | alias(libs.plugins.linkmind.plugin.feature) 4 | alias(libs.plugins.kotlin.android) 5 | } 6 | 7 | android { 8 | namespace = "org.sopt.timer" 9 | buildFeatures { 10 | viewBinding = true 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(projects.domain.timer) 16 | implementation(projects.domain.category) 17 | implementation(projects.core.datastore) 18 | } 19 | -------------------------------------------------------------------------------- /feature/timer/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/feature/timer/consumer-rules.pro -------------------------------------------------------------------------------- /feature/timer/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /feature/timer/src/main/java/org/sopt/timer/CompleteTimerViewHolder.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer 2 | 3 | import androidx.recyclerview.widget.RecyclerView 4 | import org.sopt.model.timer.Timer 5 | import org.sopt.timer.databinding.ItemTimerCompleteBinding 6 | 7 | class CompleteTimerViewHolder( 8 | private val binding: ItemTimerCompleteBinding, 9 | private val onClicked: (Timer) -> Unit, 10 | ) : RecyclerView.ViewHolder(binding.root) { 11 | fun onBind(data: Timer?) { 12 | if (data == null) return 13 | with(binding) { 14 | tvItemTimerCompleteCategory.text = data.comment 15 | val time = data.remindTime.replace("AM", "오전").replace("PM", "오후") 16 | tvItemTimerCompleteTime.text = "${data.remindDate} $time" 17 | root.setOnClickListener { 18 | onClicked(data) 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /feature/timer/src/main/java/org/sopt/timer/model/PickerItem.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.model 2 | 3 | data class PickerItem( 4 | val text: String, 5 | val isSelected: Boolean, 6 | ) { 7 | fun convertToText() = this.text.toIntOrNull()?.let { 8 | if (it < 10) "0${this.text}" else this.text 9 | } ?: this.text 10 | } 11 | -------------------------------------------------------------------------------- /feature/timer/src/main/java/org/sopt/timer/model/TimePicker.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.model 2 | 3 | data class TimePicker( 4 | val timePeriod: String, 5 | val hour: String, 6 | val minute: String, 7 | ) 8 | -------------------------------------------------------------------------------- /feature/timer/src/main/java/org/sopt/timer/model/Timer.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.model 2 | 3 | data class Timer( 4 | val id: Int, 5 | val category: String, 6 | val day: String, 7 | val am: Boolean, 8 | val hour: Int, 9 | val minute: Int, 10 | ) 11 | -------------------------------------------------------------------------------- /feature/timer/src/main/java/org/sopt/timer/settimer/TimerUiState.kt: -------------------------------------------------------------------------------- 1 | package org.sopt.timer.settimer 2 | 3 | sealed interface TimerUiState { 4 | data class BothAllowed( 5 | val data: T, 6 | ) : TimerUiState 7 | object AppAllowed : TimerUiState 8 | 9 | object DeviceAllowed : TimerUiState 10 | 11 | object NotAllowed : TimerUiState 12 | 13 | object Loading : TimerUiState 14 | 15 | object Empty : TimerUiState 16 | } 17 | -------------------------------------------------------------------------------- /feature/timer/src/main/res/layout/item_number_picker.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Link-MIND/Toaster_Android/bcc0083b90e79347e8de3e54c239caac7fe0575d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | --------------------------------------------------------------------------------