├── .dockerignore ├── .github ├── FUNDING.yml └── workflows │ └── main.yml ├── .gitignore ├── .gitlab-ci.yml ├── .releaserc.yml ├── CHANGELOG.md ├── DEPLOYMENT.md ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── REPRODUCIBLE_BUILDS.md ├── VERSION.txt ├── apkdiff.py ├── app ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── net │ │ └── schueller │ │ └── peertube │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── ic_launcher-web.png │ ├── java │ │ └── net │ │ │ └── schueller │ │ │ └── peertube │ │ │ ├── activity │ │ │ ├── AccountActivity.java │ │ │ ├── CommonActivity.java │ │ │ ├── MeActivity.java │ │ │ ├── PlaylistActivity.kt │ │ │ ├── SearchServerActivity.java │ │ │ ├── ServerAddressBookActivity.kt │ │ │ ├── SettingsActivity.java │ │ │ ├── VideoListActivity.kt │ │ │ └── VideoPlayActivity.kt │ │ │ ├── adapter │ │ │ ├── ChannelAdapter.java │ │ │ ├── MultiViewRecycleViewAdapter.kt │ │ │ ├── MultiViewRecyclerViewHolder.kt │ │ │ ├── PlaylistAdapter.kt │ │ │ ├── ServerListAdapter.kt │ │ │ └── ServerSearchAdapter.java │ │ │ ├── application │ │ │ └── AppApplication.java │ │ │ ├── database │ │ │ ├── AppDatabase.java │ │ │ ├── Server.kt │ │ │ ├── ServerDao.kt │ │ │ ├── ServerRepository.kt │ │ │ ├── ServerRoomDatabase.java │ │ │ ├── ServerViewModel.kt │ │ │ ├── Video.kt │ │ │ ├── VideoDao.kt │ │ │ ├── VideoRepository.kt │ │ │ ├── VideoRoomDatabase.java │ │ │ └── VideoViewModel.kt │ │ │ ├── fragment │ │ │ ├── AddServerFragment.kt │ │ │ ├── VideoDescriptionFragment.kt │ │ │ ├── VideoMenuQualityFragment.java │ │ │ ├── VideoMenuSpeedFragment.java │ │ │ ├── VideoMetaDataFragment.kt │ │ │ ├── VideoOptionsFragment.java │ │ │ └── VideoPlayerFragment.kt │ │ │ ├── helper │ │ │ ├── APIUrlHelper.java │ │ │ ├── ErrorHelper.java │ │ │ ├── MetaDataHelper.kt │ │ │ └── VideoHelper.java │ │ │ ├── intents │ │ │ └── Intents.kt │ │ │ ├── model │ │ │ ├── Account.kt │ │ │ ├── Avatar.kt │ │ │ ├── Category.kt │ │ │ ├── CategoryVideo.kt │ │ │ ├── Channel.kt │ │ │ ├── ChannelList.java │ │ │ ├── ChannelVideo.java │ │ │ ├── Comment.kt │ │ │ ├── CommentThread.kt │ │ │ ├── Config.java │ │ │ ├── Description.java │ │ │ ├── File.java │ │ │ ├── Language.java │ │ │ ├── Licence.java │ │ │ ├── Me.java │ │ │ ├── OauthClient.java │ │ │ ├── Overview.kt │ │ │ ├── Privacy.java │ │ │ ├── Rating.java │ │ │ ├── Redundancy.java │ │ │ ├── Resolution.java │ │ │ ├── Server.java │ │ │ ├── ServerList.java │ │ │ ├── State.java │ │ │ ├── StreamingPlaylist.java │ │ │ ├── TagVideo.kt │ │ │ ├── Token.java │ │ │ ├── Video.kt │ │ │ ├── VideoList.kt │ │ │ └── ui │ │ │ │ ├── OverviewRecycleViewItem.kt │ │ │ │ └── VideoMetaViewItem.kt │ │ │ ├── network │ │ │ ├── AccessTokenAuthenticator.java │ │ │ ├── AuthenticationService.java │ │ │ ├── AuthorizationInterceptor.java │ │ │ ├── GetConfigDataService.java │ │ │ ├── GetServerListDataService.java │ │ │ ├── GetUserService.java │ │ │ ├── GetVideoDataService.java │ │ │ ├── RetrofitInstance.java │ │ │ ├── Session.java │ │ │ └── UnsafeOkHttpClient.java │ │ │ ├── provider │ │ │ └── SearchSuggestionsProvider.java │ │ │ ├── service │ │ │ ├── LoginService.java │ │ │ └── VideoPlayerService.kt │ │ │ └── utils │ │ │ └── Extensions.kt │ └── res │ │ ├── anim │ │ ├── slide_in_bottom.xml │ │ └── slide_out_bottom.xml │ │ ├── drawable-hdpi │ │ ├── ic_action_refresh.png │ │ └── ic_action_share.png │ │ ├── drawable-mdpi │ │ ├── ic_action_refresh.png │ │ └── ic_action_share.png │ │ ├── drawable-xhdpi │ │ ├── ic_action_refresh.png │ │ └── ic_action_share.png │ │ ├── drawable-xxhdpi │ │ ├── ic_action_refresh.png │ │ └── ic_action_share.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_action_refresh.png │ │ └── ic_action_share.png │ │ ├── drawable │ │ ├── ic_baseline_account_circle_24.xml │ │ ├── ic_baseline_add_24.xml │ │ ├── ic_baseline_close_24.xml │ │ ├── ic_baseline_help_24.xml │ │ ├── ic_baseline_person_pin_24.xml │ │ ├── ic_baseline_remove_red_eye_24.xml │ │ ├── ic_baseline_settings_24.xml │ │ ├── ic_baseline_video_library_24.xml │ │ ├── ic_chevron_down.xml │ │ ├── ic_close.xml │ │ ├── ic_dashboard_black_24dp.xml │ │ ├── ic_download.xml │ │ ├── ic_edit_24.xml │ │ ├── ic_fast_forward.xml │ │ ├── ic_flag.xml │ │ ├── ic_globe.xml │ │ ├── ic_home_black_24dp.xml │ │ ├── ic_info_black_24dp.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_local.xml │ │ ├── ic_logo.xml │ │ ├── ic_logo_bw.xml │ │ ├── ic_notifications_black_24dp.xml │ │ ├── ic_pause.xml │ │ ├── ic_peertube.xml │ │ ├── ic_peertube_bw.xml │ │ ├── ic_play.xml │ │ ├── ic_playlist_add.xml │ │ ├── ic_plus_circle.xml │ │ ├── ic_rewind.xml │ │ ├── ic_search.xml │ │ ├── ic_server.xml │ │ ├── ic_share_2.xml │ │ ├── ic_slash.xml │ │ ├── ic_subscriptions.xml │ │ ├── ic_sync_black_24dp.xml │ │ ├── ic_thumbs_down.xml │ │ ├── ic_thumbs_down_filled.xml │ │ ├── ic_thumbs_up.xml │ │ ├── ic_thumbs_up_filled.xml │ │ ├── ic_trending.xml │ │ ├── ic_user.xml │ │ └── test_image.gif │ │ ├── layout │ │ ├── activity_account.xml │ │ ├── activity_me.xml │ │ ├── activity_playlist.xml │ │ ├── activity_search_server.xml │ │ ├── activity_server_address_book.xml │ │ ├── activity_settings.xml │ │ ├── activity_video_list.xml │ │ ├── activity_video_play.xml │ │ ├── fragment_add_server.xml │ │ ├── fragment_video_description.xml │ │ ├── fragment_video_meta.xml │ │ ├── fragment_video_options_popup_menu.xml │ │ ├── fragment_video_options_quality_popup_menu.xml │ │ ├── fragment_video_options_speed_popup_menu.xml │ │ ├── fragment_video_player.xml │ │ ├── item_category_title.xml │ │ ├── item_channel_title.xml │ │ ├── item_tag_title.xml │ │ ├── item_video_comments_overview.xml │ │ ├── item_video_meta.xml │ │ ├── row_account_about.xml │ │ ├── row_account_channels.xml │ │ ├── row_account_video.xml │ │ ├── row_playlist.xml │ │ ├── row_popup_menu.xml │ │ ├── row_search_server.xml │ │ ├── row_server_address_book.xml │ │ ├── row_video_list.xml │ │ └── video_playback_controls.xml │ │ ├── menu │ │ ├── menu_bottom_account.xml │ │ ├── menu_bottom_video_list.xml │ │ ├── menu_top_account.xml │ │ ├── menu_top_videolist.xml │ │ ├── menu_video_more.xml │ │ ├── menu_video_play_options.xml │ │ └── menu_video_row_mode.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values-ar │ │ └── strings.xml │ │ ├── values-bn-rBD │ │ └── strings.xml │ │ ├── values-bn │ │ └── strings.xml │ │ ├── values-ca │ │ └── strings.xml │ │ ├── values-cs │ │ └── strings.xml │ │ ├── values-de │ │ └── strings.xml │ │ ├── values-el │ │ └── strings.xml │ │ ├── values-eo │ │ └── strings.xml │ │ ├── values-es │ │ └── strings.xml │ │ ├── values-fa │ │ └── strings.xml │ │ ├── values-fi │ │ └── strings.xml │ │ ├── values-fr │ │ └── strings.xml │ │ ├── values-gd │ │ └── strings.xml │ │ ├── values-hi │ │ └── strings.xml │ │ ├── values-ia │ │ └── strings.xml │ │ ├── values-id │ │ └── strings.xml │ │ ├── values-it │ │ └── strings.xml │ │ ├── values-ja │ │ └── strings.xml │ │ ├── values-ks │ │ └── strings.xml │ │ ├── values-nb-rNO │ │ └── strings.xml │ │ ├── values-nl │ │ └── strings.xml │ │ ├── values-pl │ │ └── strings.xml │ │ ├── values-pt-rBR │ │ └── strings.xml │ │ ├── values-pt │ │ └── strings.xml │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values-sc │ │ └── strings.xml │ │ ├── values-si │ │ └── strings.xml │ │ ├── values-sq │ │ └── strings.xml │ │ ├── values-sv │ │ └── strings.xml │ │ ├── values-tr │ │ └── strings.xml │ │ ├── values-uk │ │ └── strings.xml │ │ ├── values-zh-rCN │ │ └── strings.xml │ │ ├── values-zh-rTW │ │ └── strings.xml │ │ ├── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── constants.xml │ │ ├── dimens.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── backup_descriptor.xml │ │ ├── root_preferences.xml │ │ └── searchable.xml │ └── test │ └── java │ └── net │ └── schueller │ └── peertube │ └── ExampleUnitTest.java ├── build.gradle ├── ci-scripts ├── make-github-release.sh └── validate-play-store-lang.sh ├── fastlane ├── Appfile ├── Fastfile └── metadata │ └── android │ ├── ar │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── bn-BD │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ └── 1057.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── ca │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ └── 1049.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── de-DE │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ └── 1052.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── en-US │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ ├── 1057.txt │ │ ├── 1058.txt │ │ ├── 1059.txt │ │ ├── 1060.txt │ │ ├── 1061.txt │ │ ├── 1062.txt │ │ ├── 1063.txt │ │ ├── 1064.txt │ │ ├── 1065.txt │ │ ├── 1066.txt │ │ ├── 1067.txt │ │ ├── 1068.txt │ │ ├── 1069.txt │ │ ├── 1070.txt │ │ ├── 1071.txt │ │ ├── 1072.txt │ │ ├── 1073.txt │ │ ├── 1074.txt │ │ ├── 1075.txt │ │ ├── 1076.txt │ │ ├── 1077.txt │ │ ├── 1078.txt │ │ ├── 1079.txt │ │ └── 1080.txt │ ├── full_description.txt │ ├── images │ │ ├── featureGraphic.png │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── 1_en-US.png │ │ │ ├── 2_en-US.png │ │ │ ├── 3_en-US.png │ │ │ ├── 4_en-US.png │ │ │ └── 5_en-US.png │ ├── short_description.txt │ └── title.txt │ ├── es-ES │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ └── 1057.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── fa │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ └── 1057.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── fi-FI │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ └── 1057.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── fr-FR │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ ├── 1057.txt │ │ ├── 1058.txt │ │ ├── 1059.txt │ │ ├── 1060.txt │ │ ├── 1061.txt │ │ ├── 1062.txt │ │ ├── 1063.txt │ │ ├── 1064.txt │ │ ├── 1065.txt │ │ ├── 1066.txt │ │ ├── 1067.txt │ │ ├── 1068.txt │ │ └── 1069.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── id │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1052.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ └── 1057.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── it-IT │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ └── 1057.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── no-NO │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ └── 1054.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── pl-PL │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── pt-BR │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1064.txt │ │ ├── 1065.txt │ │ ├── 1066.txt │ │ ├── 1067.txt │ │ ├── 1068.txt │ │ └── 1069.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── pt-PT │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ ├── 1057.txt │ │ ├── 1058.txt │ │ ├── 1059.txt │ │ └── 1060.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── ru-RU │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ ├── 1057.txt │ │ └── 1058.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── si-LK │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── sq │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ ├── 1057.txt │ │ ├── 1058.txt │ │ ├── 1059.txt │ │ ├── 1060.txt │ │ ├── 1062.txt │ │ ├── 1063.txt │ │ ├── 1064.txt │ │ ├── 1065.txt │ │ ├── 1066.txt │ │ ├── 1067.txt │ │ ├── 1068.txt │ │ └── 1069.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── tr-TR │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ ├── 1057.txt │ │ ├── 1058.txt │ │ ├── 1059.txt │ │ ├── 1060.txt │ │ ├── 1061.txt │ │ ├── 1062.txt │ │ ├── 1063.txt │ │ ├── 1064.txt │ │ ├── 1065.txt │ │ ├── 1066.txt │ │ ├── 1067.txt │ │ ├── 1068.txt │ │ └── 1069.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ ├── uk │ ├── changelogs │ │ ├── 1047.txt │ │ ├── 1048.txt │ │ ├── 1049.txt │ │ ├── 1050.txt │ │ ├── 1051.txt │ │ ├── 1052.txt │ │ ├── 1053.txt │ │ ├── 1054.txt │ │ ├── 1055.txt │ │ ├── 1056.txt │ │ ├── 1057.txt │ │ ├── 1058.txt │ │ ├── 1059.txt │ │ ├── 1060.txt │ │ ├── 1061.txt │ │ ├── 1062.txt │ │ ├── 1063.txt │ │ ├── 1064.txt │ │ ├── 1065.txt │ │ ├── 1066.txt │ │ ├── 1067.txt │ │ ├── 1068.txt │ │ └── 1069.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt │ └── zh-TW │ ├── changelogs │ ├── 1047.txt │ ├── 1048.txt │ ├── 1049.txt │ ├── 1050.txt │ ├── 1051.txt │ ├── 1052.txt │ ├── 1053.txt │ ├── 1054.txt │ ├── 1055.txt │ ├── 1056.txt │ ├── 1057.txt │ ├── 1058.txt │ ├── 1059.txt │ ├── 1060.txt │ ├── 1062.txt │ └── 1063.txt │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [sschueller] 4 | liberapay: sschueller/donate 5 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | branches: [develop] 6 | types: [opened, edited, synchronize] 7 | 8 | jobs: 9 | check-for-cc: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | 15 | - name: check-for-cc 16 | id: check-for-cc 17 | uses: agenthunt/conventional-commit-checker-action@v1.0.0 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # generated files 2 | bin/ 3 | gen/ 4 | 5 | # Local configuration file (sdk path, etc) 6 | local.properties 7 | 8 | # Windows thumbnail db 9 | Thumbs.db 10 | 11 | # OSX files 12 | .DS_Store 13 | 14 | # Android Studio 15 | *.iml 16 | .idea 17 | .gradle 18 | build/ 19 | .navigation 20 | captures/ 21 | 22 | #NDK 23 | .externalNativeBuild -------------------------------------------------------------------------------- /.releaserc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | plugins: 3 | - "@semantic-release/commit-analyzer" 4 | - - "@semantic-release/release-notes-generator" 5 | - linkReferences: false 6 | linkCompare: false 7 | - - "@semantic-release/exec" 8 | - verifyReleaseCmd: "echo ${nextRelease.version} > VERSION.txt" 9 | generateNotesCmd: "if [[ ! -f RELEASE_NOTES.txt ]]; then echo '${nextRelease.notes.trim()}' > RELEASE_NOTES.txt; fi && echo '${nextRelease.notes.trim()}' > fastlane/metadata/android/en-US/changelogs/$(cat VERSION_CODE.txt).txt" 10 | - - "@semantic-release/changelog" 11 | - changelogFile: CHANGELOG.md 12 | - - "@semantic-release/git" 13 | - assets: 14 | - 'app/build.gradle' 15 | - 'CHANGELOG.md' 16 | - 'VERSION.txt' 17 | - "fastlane/metadata/android/en-US/changelogs/*.txt" 18 | message: "chore(release): ${nextRelease.version} [only cd]\n\n${nextRelease.notes}" 19 | - "@semantic-release/gitlab" 20 | 21 | branches: 22 | - "master" 23 | - "+([0-9])?(.{+([0-9]),x}).x" 24 | - name: "alpha" 25 | prerelease: "alpha" 26 | -------------------------------------------------------------------------------- /DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | ## Internal deployment notes 2 | 3 | 1. merge pull-requests on github into develop 4 | 2. Locally switch to develop 5 | 3. Pull github develop 6 | 4. Pull weblate develop 7 | 5. Push to develop gitlab 8 | 6. Merge develop into master and merge 9 | 7. Wait for Release Build and release to play store 10 | 8. Wait for gitlab -> github sync 11 | 9. Run publishGithub 12 | 10. Merge master into develop, push to github 13 | 14 | 15 | ## fastlane update (install ruby2.7 and "gem-2.7 install bundler") 16 | ``` 17 | bundle-2.7 update 18 | ``` -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | -------------------------------------------------------------------------------- /VERSION.txt: -------------------------------------------------------------------------------- 1 | 1.12.2 2 | -------------------------------------------------------------------------------- /app/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 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/net/schueller/peertube/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package net.schueller.peertube; 2 | 3 | import android.content.Context; 4 | import androidx.test.InstrumentationRegistry; 5 | import androidx.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("net.schueller.peertube", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sschueller/peertube-android/3b88b039e999d1e9802f0b80a41c00ba4321f773/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sschueller/peertube-android/3b88b039e999d1e9802f0b80a41c00ba4321f773/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/application/AppApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Stefan Schüller 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package net.schueller.peertube.application; 18 | 19 | import android.app.Application; 20 | import android.content.Context; 21 | 22 | public class AppApplication extends Application { 23 | private static Application instance; 24 | 25 | @Override 26 | public void onCreate() { 27 | super.onCreate(); 28 | instance = this; 29 | } 30 | 31 | public static Context getContext() { 32 | return instance.getApplicationContext(); 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/database/AppDatabase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Stefan Schüller 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package net.schueller.peertube.database; 18 | 19 | import androidx.room.Database; 20 | import androidx.room.RoomDatabase; 21 | 22 | @Database(entities = {Server.class, Video.class}, version = 1) 23 | public abstract class AppDatabase extends RoomDatabase { 24 | public abstract ServerDao serverDao(); 25 | 26 | public abstract VideoDao videoDao(); 27 | } -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/database/Server.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Stefan Schüller 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package net.schueller.peertube.database 18 | 19 | import android.os.Parcelable 20 | import androidx.room.PrimaryKey 21 | import androidx.room.ColumnInfo 22 | import androidx.room.Entity 23 | import kotlinx.parcelize.Parcelize 24 | 25 | @Parcelize 26 | @Entity(tableName = "server_table") 27 | data class Server( 28 | 29 | @PrimaryKey(autoGenerate = true) 30 | var id: Int = 0, 31 | 32 | @ColumnInfo(name = "server_name") 33 | var serverName: String, 34 | 35 | @ColumnInfo(name = "server_host") 36 | var serverHost: String? = null, 37 | 38 | @ColumnInfo(name = "username") 39 | var username: String? = null, 40 | 41 | @ColumnInfo(name = "password") 42 | var password: String? = null 43 | 44 | ) : Parcelable -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/database/ServerDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Stefan Schüller 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package net.schueller.peertube.database 18 | 19 | import androidx.lifecycle.LiveData 20 | import androidx.room.* 21 | 22 | @Dao 23 | interface ServerDao { 24 | 25 | @Insert 26 | suspend fun insert(server: Server) 27 | 28 | @Update 29 | suspend fun update(server: Server) 30 | 31 | @Query("DELETE FROM server_table") 32 | suspend fun deleteAll() 33 | 34 | @Delete 35 | suspend fun delete(server: Server) 36 | 37 | @get:Query("SELECT * from server_table ORDER BY server_name DESC") 38 | val allServers: LiveData> 39 | } -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/database/Video.kt: -------------------------------------------------------------------------------- 1 | package net.schueller.peertube.database 2 | 3 | import android.os.Parcelable 4 | import androidx.room.ColumnInfo 5 | import androidx.room.Entity 6 | import androidx.room.PrimaryKey 7 | import kotlinx.parcelize.Parcelize 8 | import java.util.* 9 | 10 | @Parcelize 11 | @Entity(tableName = "watch_later") 12 | data class Video( 13 | @PrimaryKey(autoGenerate = true) 14 | var id: Int = 0, 15 | 16 | @ColumnInfo(name = "video_uuid") 17 | var videoUUID: String, 18 | 19 | @ColumnInfo(name = "video_name") 20 | var videoName: String, 21 | 22 | @ColumnInfo(name = "video_description") 23 | var videoDescription: String? 24 | 25 | ) : Parcelable -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/database/VideoDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Stefan Schüller 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package net.schueller.peertube.database 18 | 19 | import androidx.lifecycle.LiveData 20 | import androidx.room.* 21 | 22 | @Dao 23 | interface VideoDao { 24 | 25 | @Insert 26 | suspend fun insert(video: Video) 27 | 28 | @Update 29 | suspend fun update(video: Video) 30 | 31 | @Query("DELETE FROM watch_later") 32 | suspend fun deleteAll() 33 | 34 | @Delete 35 | suspend fun delete(video: Video) 36 | 37 | @get:Query("SELECT * from watch_later ORDER BY video_name DESC") 38 | val allVideos: LiveData> 39 | } -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/model/Account.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Stefan Schüller 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package net.schueller.peertube.model 18 | 19 | import java.util.Date 20 | 21 | class Account( 22 | var id: Int, 23 | var url: String, 24 | var uuid: String, 25 | var name: String, 26 | var host: String, 27 | var followingCount: Int, 28 | var followersCount: Int, 29 | var avatar: Avatar?, 30 | var createdAt: Date, 31 | var updatedAt: Date, 32 | var displayName: String, 33 | var description: String 34 | ) -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/model/Avatar.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Stefan Schüller 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package net.schueller.peertube.model 18 | 19 | import java.util.Date 20 | 21 | class Avatar( 22 | var path: String, 23 | var createdAt: Date, 24 | var updatedAt: Date 25 | ) -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/model/Category.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Stefan Schüller 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Affero General Public License as 6 | * published by the Free Software Foundation, either version 3 of the 7 | * License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU Affero General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Affero General Public License 15 | * along with this program. If not, see . 16 | */ 17 | package net.schueller.peertube.model 18 | 19 | import net.schueller.peertube.model.ui.OverviewRecycleViewItem 20 | 21 | class Category: OverviewRecycleViewItem() { 22 | 23 | var id: Int? = null 24 | var label: String? = null 25 | } -------------------------------------------------------------------------------- /app/src/main/java/net/schueller/peertube/model/CategoryVideo.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Stefan Schüller 3 | * 4 | * License: GPL-3.0+ 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | package net.schueller.peertube.model 19 | 20 | import java.util.ArrayList 21 | 22 | class CategoryVideo( 23 | val category: Category, 24 | val videos: ArrayList