mirror of
https://github.com/NiciDieNase/chaosflix
synced 2024-11-23 04:43:07 +00:00
Merge branch 'develop' into feature/leanbackChannel
This commit is contained in:
commit
d0ed9eaeae
15 changed files with 163 additions and 144 deletions
1
common/proguard-rules.pro
vendored
1
common/proguard-rules.pro
vendored
|
@ -22,6 +22,7 @@
|
|||
-ignorewarnings
|
||||
|
||||
-keep @interface androidx.support.annotation.Keep
|
||||
-keep @interface androidx.room.Entity
|
||||
|
||||
## Start Retrofit-Rules
|
||||
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
|
||||
|
|
|
@ -10,5 +10,5 @@ class ProgressEventView(
|
|||
@Embedded
|
||||
val progress: PlaybackProgress,
|
||||
@Relation(entityColumn = "guid", parentColumn = "event_guid")
|
||||
var event: Event
|
||||
var event: Event?
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ import androidx.room.Index
|
|||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "watchlist_item",
|
||||
indices = arrayOf(Index(value = ["event_guid"], unique = true)))
|
||||
indices = [Index(value = ["event_guid"], unique = true)])
|
||||
data class WatchlistItem(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0,
|
||||
|
|
|
@ -60,13 +60,14 @@ class BrowseViewModel(
|
|||
mediaRepository.updateConferencesAndGroups()
|
||||
|
||||
fun updateEventsForConference(conference: Conference): LiveData<LiveEvent<MediaRepository.State, List<Event>, String>> =
|
||||
LiveDataMerger<List<Event>, LiveEvent<MediaRepository.State, List<Event>, String>, LiveEvent<MediaRepository.State, List<Event>, String>>()
|
||||
.merge(
|
||||
getEventsforConference(conference),
|
||||
mediaRepository.updateEventsForConference(conference)
|
||||
) { list: List<Event>?, liveEvent: LiveEvent<MediaRepository.State, List<Event>, String>? ->
|
||||
return@merge LiveEvent(liveEvent?.state ?: MediaRepository.State.DONE, list ?: liveEvent?.data, liveEvent?.error)
|
||||
}
|
||||
LiveDataMerger<List<Event>, LiveEvent<MediaRepository.State, List<Event>, String>, LiveEvent<MediaRepository.State, List<Event>, String>>()
|
||||
.merge(
|
||||
getEventsforConference(conference),
|
||||
mediaRepository.updateEventsForConference(conference)
|
||||
) { list: List<Event>?, liveEvent: LiveEvent<MediaRepository.State, List<Event>, String>? ->
|
||||
return@merge LiveEvent(liveEvent?.state ?: MediaRepository.State.DONE, list
|
||||
?: liveEvent?.data, liveEvent?.error)
|
||||
}
|
||||
|
||||
fun getBookmarkedEvents(): LiveData<List<Event>> {
|
||||
val itemDao = database.watchlistItemDao()
|
||||
|
@ -91,13 +92,14 @@ class BrowseViewModel(
|
|||
}
|
||||
return Transformations.map(dao.getAllWithEvent()) { list ->
|
||||
return@map if (filterFinished) {
|
||||
val result = list.partition { it.progress.progress / 1000 > (it.event.length - 10) }
|
||||
Log.d(TAG, "Filtered ${result.first.size} finished items: ${result.first.map { "${it.progress.progress / 1000}-${it.event.length}|"}}")
|
||||
result.second.map { it.event.apply { it.event.progress = it.progress.progress } }
|
||||
} else {
|
||||
list.map { it.event.apply { it.event.progress = it.progress.progress } }
|
||||
}
|
||||
val result = list.partition { it.progress.progress / 1000 + 10 < it.event?.length ?: 0 }
|
||||
Log.i(TAG, "Could not load events for ${list.filter { it.event == null }.map{it.progress.eventGuid}}")
|
||||
Log.i(TAG, "Filtered ${result.first.size} finished items: ${result.first.map { "${it.progress.progress / 1000}-${it.event?.length}|" }}")
|
||||
result.second.mapNotNull { it.event.apply { it.event?.progress = it.progress.progress } }
|
||||
} else {
|
||||
list.mapNotNull { it.event?.apply { it.event?.progress = it.progress.progress } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getPromotedEvents(): LiveData<List<Event>> = database.eventDao().findPromotedEvents()
|
||||
|
@ -128,6 +130,7 @@ class BrowseViewModel(
|
|||
offlineItemManager.deleteOfflineItem(guid)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAutoselectStream() = preferencesManager.autoselectStream
|
||||
|
||||
fun searchEventsPaged(query: String): LiveData<PagedList<Event>> {
|
||||
|
|
|
@ -8,6 +8,8 @@ import com.google.gson.Gson
|
|||
import de.nicidienase.chaosflix.common.AnalyticsWrapper
|
||||
import de.nicidienase.chaosflix.common.AnalyticsWrapperImpl
|
||||
import de.nicidienase.chaosflix.common.mediadata.MediaRepository
|
||||
import de.nicidienase.chaosflix.common.userdata.entities.progress.PlaybackProgress
|
||||
import de.nicidienase.chaosflix.common.userdata.entities.progress.PlaybackProgressDao
|
||||
import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem
|
||||
import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItemDao
|
||||
import de.nicidienase.chaosflix.common.util.LiveEvent
|
||||
|
@ -22,6 +24,7 @@ import kotlinx.coroutines.launch
|
|||
class PreferencesViewModel(
|
||||
private val mediaRepository: MediaRepository,
|
||||
private val watchlistItemDao: WatchlistItemDao,
|
||||
private val progressItemDao: PlaybackProgressDao,
|
||||
private val exportDir: File
|
||||
) : ViewModel() {
|
||||
private val gson = Gson()
|
||||
|
@ -43,23 +46,48 @@ class PreferencesViewModel(
|
|||
val favorites = watchlistItemDao.getAllSync()
|
||||
val json = gson.toJson(favorites)
|
||||
Log.d(TAG, json)
|
||||
if (exportDir.isDirectory) {
|
||||
val file = File("${exportDir.path}${File.separator}$FAVORITES_FILENAME")
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
file.createNewFile()
|
||||
}
|
||||
try {
|
||||
val fileWriter = FileWriter(file)
|
||||
val bufferedWriter = BufferedWriter(fileWriter)
|
||||
bufferedWriter.write(json)
|
||||
bufferedWriter.close()
|
||||
fileWriter.close()
|
||||
Log.d(TAG, file.path)
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
writeJsonToFile(json, exportDir, FAVORITES_FILENAME)
|
||||
|
||||
val progress = progressItemDao.getAllSync()
|
||||
val progressJson = gson.toJson(progress)
|
||||
Log.d(TAG, progressJson)
|
||||
writeJsonToFile(progressJson, exportDir, PROGRESS_FILENAME)
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeJsonToFile(json: String, exportDir: File, fileName: String) {
|
||||
if (exportDir.isDirectory) {
|
||||
val file = File("${exportDir.path}${File.separator}$fileName")
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
file.createNewFile()
|
||||
}
|
||||
try {
|
||||
val fileWriter = FileWriter(file)
|
||||
val bufferedWriter = BufferedWriter(fileWriter)
|
||||
bufferedWriter.write(json)
|
||||
bufferedWriter.close()
|
||||
fileWriter.close()
|
||||
Log.d(TAG, file.path)
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun readJsonFromFile(exportDir: File, fileName: String): String? {
|
||||
return try {
|
||||
val file = File("${exportDir.path}${File.separator}$fileName")
|
||||
if (file.exists()) {
|
||||
val fileReader = FileReader(file)
|
||||
val bufferedReader = BufferedReader(fileReader)
|
||||
bufferedReader.readText()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Log.d(TAG, ex.message, ex)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,20 +95,20 @@ class PreferencesViewModel(
|
|||
val mutableLiveData = MutableLiveData<LiveEvent<State, List<WatchlistItem>, Exception>>()
|
||||
mutableLiveData.postValue(LiveEvent(State.Loading, null, null))
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val file = File("${exportDir.path}${File.separator}$FAVORITES_FILENAME")
|
||||
try {
|
||||
if (file.exists()) {
|
||||
val fileReader = FileReader(file)
|
||||
val bufferedReader = BufferedReader(fileReader)
|
||||
val json: String = bufferedReader.readText()
|
||||
val fromJson = gson.fromJson(json, Array<WatchlistItem>::class.java)
|
||||
fromJson.map { watchlistItemDao.saveItem(WatchlistItem(eventGuid = it.eventGuid)) }
|
||||
mutableLiveData.postValue(LiveEvent(State.Done, fromJson.asList(), null))
|
||||
} else {
|
||||
mutableLiveData.postValue(LiveEvent(State.Done, null, null))
|
||||
val favoritesJson = readJsonFromFile(exportDir, FAVORITES_FILENAME)
|
||||
val progressJson = readJsonFromFile(exportDir, PROGRESS_FILENAME)
|
||||
if (favoritesJson == null && progressJson == null) {
|
||||
mutableLiveData.postValue(LiveEvent(State.Done, null, null))
|
||||
} else {
|
||||
favoritesJson?.let {
|
||||
val fromJson = gson.fromJson(it, Array<WatchlistItem>::class.java)
|
||||
fromJson.map { watchlistItemDao.saveItem(it) }
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
mutableLiveData.postValue(LiveEvent(State.Done, null, ex))
|
||||
progressJson?.let {
|
||||
val fromJson = gson.fromJson(it, Array<PlaybackProgress>::class.java)
|
||||
fromJson.map { progressItemDao.saveProgress(it) }
|
||||
}
|
||||
mutableLiveData.postValue(LiveEvent(State.Done, error = null))
|
||||
}
|
||||
}
|
||||
return mutableLiveData
|
||||
|
@ -93,5 +121,6 @@ class PreferencesViewModel(
|
|||
companion object {
|
||||
private val TAG = PreferencesViewModel::class.java.simpleName
|
||||
private const val FAVORITES_FILENAME = "chaosflix_favorites.json"
|
||||
private const val PROGRESS_FILENAME = "chaosflix_progress.json"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ class ViewModelFactory private constructor(context: Context) : ViewModelProvider
|
|||
PreferencesViewModel::class.java -> PreferencesViewModel(
|
||||
mediaRepository,
|
||||
database.watchlistItemDao(),
|
||||
database.playbackProgressDao(),
|
||||
externalFilesDir
|
||||
) as T
|
||||
FavoritesImportViewModel::class.java -> FavoritesImportViewModel(
|
||||
|
|
|
@ -1,53 +1,106 @@
|
|||
<resources>
|
||||
<string name="api_media_ccc_url" translatable="false">https://api.media.ccc.de</string>
|
||||
<string name="streaming_media_ccc_url" translatable="false">https://streaming.media.ccc.de</string>
|
||||
<string name="app_name" translatable="false">Chaosflix</string>
|
||||
|
||||
<string name="app_name">Chaosflix</string>
|
||||
<string name="related_movies">Related Videos</string>
|
||||
<!--Actions-->
|
||||
<string name="error">Error</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="pause">Pause</string>
|
||||
<string name="play">Play</string>
|
||||
<string name="stop">Stop</string>
|
||||
<string name="dismiss_error">Dismiss</string>
|
||||
<string name="start_again">Start again</string>
|
||||
<string name="resume">Resume</string>
|
||||
<string name="resume_question">Resume previous position or start from beginning</string>
|
||||
<string name="return_to_homescreen">Return to Homescreen</string>
|
||||
<string name="bookmark">Bookmark</string>
|
||||
|
||||
<!--Content-->
|
||||
<string name="related_movies">Related Videos</string>
|
||||
<string name="random_talks_on_this_track">Random Talks in the same Track</string>
|
||||
<string name="random_talks">Other random Talks at this Conference</string>
|
||||
<string name="related_talks">Related Talks</string>
|
||||
<string name="recordings">Recordings</string>
|
||||
<string name="conferences">Conferences</string>
|
||||
<string name="recommendations">Recommendations</string>
|
||||
<string name="bookmarks">Bookmarks</string>
|
||||
|
||||
<!--Watchlist-->
|
||||
<string name="watchlist_dialog_needed">new-watchlist</string>
|
||||
<string name="watchlist_message">You can find you watchlist on the Homescreen of Chaosflix</string>
|
||||
<string name="watchlist">Watchlist</string>
|
||||
<string name="remove_from_watchlist">Remove from Watchlist</string>
|
||||
<string name="add_to_watchlist">Add to Watchlist</string>
|
||||
|
||||
<!--Error Messages-->
|
||||
<string name="oops">Oops</string>
|
||||
<string name="error_event_not_found">Event not found</string>
|
||||
<string name="no_recording_found_for">No Recording found for</string>
|
||||
<string name="video_error_media_load_timeout">Media loading timed out</string>
|
||||
<string name="video_error_server_inaccessible">Media server was not reachable</string>
|
||||
<string name="video_error_unknown_error">Failed to load video</string>
|
||||
<string name="error_fragment_message">An error occurred</string>
|
||||
<string name="dismiss_error">Dismiss</string>
|
||||
<string name="oops">Oops</string>
|
||||
<string name="random_talks_on_this_track">Random Talks in the same Track</string>
|
||||
<string name="random_talks">Other random Talks at this Conference</string>
|
||||
<string name="resume_question">Resume previous position or start from beginning</string>
|
||||
<string name="start_again">Start again</string>
|
||||
<string name="resume">Resume</string>
|
||||
<string name="related_talks">Related Talks</string>
|
||||
<string name="recomendations">Recomendations</string>
|
||||
<string name="watchlist">Watchlist</string>
|
||||
<string name="recordings">Recordings</string>
|
||||
|
||||
<!--Livestreams-->
|
||||
<string name="streaming_prefix">[streaming]</string>
|
||||
<string name="conferences">Conferences</string>
|
||||
<string name="remove_from_watchlist">Remove from Watchlist</string>
|
||||
<string name="add_to_watchlist">Add to Watchlist</string>
|
||||
<string name="streams">Streams</string>
|
||||
<string name="livestreams">Livestreams</string>
|
||||
<string name="watchlist_message">You can find you watchlist on the Homescreen of Chaosflix</string>
|
||||
|
||||
<!--About-->
|
||||
<string name="about_chaosflix">About Chaosflix</string>
|
||||
<string name="about">About</string>
|
||||
<string name="privacy_policy">Chaosflix does not collect or transmit any personalized data.</string>
|
||||
<string name="about_description">Chaosflix was developed, because the developer was annoyed
|
||||
that there was an app for Apple-TV but not Android- and Fire-TV. So now, after the
|
||||
TV-app there is also one for (android) phones and tablets. Enjoy!</string>
|
||||
<string name="related_events">Related Events</string>
|
||||
<string name="about_github">Find the source on Github</string>
|
||||
<string name="about_beta">Become a Beta-Tester</string>
|
||||
<string name="about_twitter">Follow the developer on Twitter</string>
|
||||
<string name="about_playstore">Rate us on Google Play</string>
|
||||
<string name="about_title">Chaosflix</string>
|
||||
<string name="about_voctocat"> The Vocotocat-Logo was designed by Sebastian Morr and is released under CC BY-NC-SA 4.0</string>
|
||||
<string name="chaosflix_licence">Chaosflix is released under MIT-License.</string>
|
||||
|
||||
<!--Preferences-->
|
||||
<string name="watchlist_preferences_key">watchlist</string>
|
||||
<string name="watchlist_dialog_needed">new-watchlist</string>
|
||||
<string name="return_to_homescreen">Return to Homescreen</string>
|
||||
<string name="clean_cache">Clean Cache</string>
|
||||
<string name="clean_cache">Clean Cache</string>
|
||||
<string name="download_folder">Download folder</string>
|
||||
<string name="pref_autoselect_recording">Don\'t show selection dialog, just use HD-mp4</string>
|
||||
<string name="pref_autoselect_stream">Don\'t show selection dialog, just use DASH</string>
|
||||
<string name="pref_mobile_downloads">Enable downloads over mobile or payed networks</string>
|
||||
<string name="export_favorites">Export Favorites</string>
|
||||
<string name="import_favorites">Import to Favorites</string>
|
||||
<string name="pref_external_player">Always use external player</string>
|
||||
<string name="setting_choose_stream">Automatically choose stream</string>
|
||||
<string name="setting_metered_networks">Allow downloads over metered networks</string>
|
||||
<string name="settings_choose_recording">Automatically choose recording</string>
|
||||
<string name="export_favorites">Export Favorites</string>
|
||||
<string name="import_favorites">Import to Favorites</string>
|
||||
<string name="error_event_not_found">Event not found</string>
|
||||
<string name="privacy_policy">Chaosflix does not collect or transmit any personalized data.</string>
|
||||
<string name="no_recording_found_for">No Recording found for</string>
|
||||
|
||||
<!--Moved from touch-->
|
||||
<string name="thumbnail">thumbnail</string>
|
||||
<string name="search_title">Search</string>
|
||||
<string name="download">Download</string>
|
||||
<string name="downloads">Downloads</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="titleimage">TitleImage</string>
|
||||
<string name="search_events">Search Events</string>
|
||||
<string name="search_talks">Search Talks</string>
|
||||
<string name="event_details_image_thumbnail_description">Thumbnail-picture for this event</string>
|
||||
<string name="continue_watching">Continue Watching</string>
|
||||
<string name="preferences">Preferences</string>
|
||||
<string name="drawer_open">Drawer open</string>
|
||||
<string name="drawer_close">Drawer closed</string>
|
||||
<string name="remove_bookmark">Remove Bookmark</string>
|
||||
<string name="delete_local_file">Delete local File</string>
|
||||
<string name="showLibs">Libraries we use</string>
|
||||
<string name="reload">Reload</string>
|
||||
<string name="no_livestreams">Currently no livestreams</string>
|
||||
<string name="share_description">Watch this video from media.ccc.de</string>
|
||||
<string name="select_stream">Select Stream</string>
|
||||
<string name="play_button">Play-Button</string>
|
||||
<string name="list_of_events">List of Events</string>
|
||||
<string name="delete_item">Delete Item</string>
|
||||
<string name="import_activity_label">Fahrplan-Import</string>
|
||||
<string name="select_all">Select all</string>
|
||||
</resources>
|
||||
|
|
|
@ -72,14 +72,14 @@ class ConferencesBrowseFragment : BrowseSupportFragment() {
|
|||
watchListAdapter = ChaosflixEventAdapter(eventPresenter)
|
||||
inProgressAdapter = ChaosflixEventAdapter(eventPresenter)
|
||||
promotedAdapter = ChaosflixEventAdapter(eventPresenter)
|
||||
promotedRow = ListRow(HeaderItem(getString(R.string.recommended)), promotedAdapter)
|
||||
promotedRow = ListRow(HeaderItem(getString(R.string.recommendations)), promotedAdapter)
|
||||
watchlistRow = ListRow(HeaderItem(getString(R.string.watchlist)), watchListAdapter)
|
||||
inProgressRow = ListRow(HeaderItem(getString(R.string.continue_watching)), inProgressAdapter)
|
||||
|
||||
// Sections and Divider
|
||||
streamingSection = SectionRow(HeaderItem(getString(R.string.livestreams)))
|
||||
streamsDivider = DividerRow()
|
||||
recomendationsSections = SectionRow(HeaderItem(getString(R.string.recomendations)))
|
||||
recomendationsSections = SectionRow(HeaderItem(getString(R.string.recommendations)))
|
||||
recomendationsDivider = DividerRow()
|
||||
conferencesSection = SectionRow(HeaderItem(getString(R.string.conferences)))
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="recommended">Recommended</string>
|
||||
<string name="continue_watching">Continue Watching</string>
|
||||
<string name="pref_external_player">Use external player</string>
|
||||
</resources>
|
|
@ -21,7 +21,7 @@ android {
|
|||
targetSdkVersion rootProject.ext.targetSDK
|
||||
manifestPlaceholders = [label: appName]
|
||||
// odd for touch, even for leanback
|
||||
versionCode 1
|
||||
versionCode 298
|
||||
versionName versionString
|
||||
|
||||
if(project.hasProperty("versionCode")){
|
||||
|
|
|
@ -40,7 +40,7 @@ class AboutFragment : Fragment() {
|
|||
val version = pInfo.versionName
|
||||
val aboutView = AboutPage(requireContext())
|
||||
.setImage(R.drawable.icon_primary_background)
|
||||
.setDescription(resources.getString(R.string.description))
|
||||
.setDescription(resources.getString(R.string.about_description))
|
||||
.addItem(Element().setTitle("Version $version"))
|
||||
.addWebsite(
|
||||
getString(R.string.about_licence_url),
|
||||
|
|
|
@ -367,7 +367,7 @@ class EventDetailsFragment : Fragment() {
|
|||
val event = viewModel.event.value
|
||||
if (event != null) {
|
||||
val shareIntent = Intent(Intent.ACTION_SEND, Uri.parse(event.frontendLink))
|
||||
shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.watch_this))
|
||||
shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_description))
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, event.frontendLink)
|
||||
shareIntent.type = "text/plain"
|
||||
startActivity(shareIntent)
|
||||
|
|
|
@ -13,6 +13,6 @@ class SettingsActivity : AppCompatActivity() {
|
|||
.setContentView<ActivitySettingsBinding>(this, R.layout.activity_settings)
|
||||
setSupportActionBar(binding.toolbarInc.toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.setTitle(R.string.settings)
|
||||
supportActionBar?.setTitle(R.string.preferences)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:backgroundTint="@color/primary"
|
||||
android:text="@string/import_label"
|
||||
android:text="@string/bookmark"
|
||||
android:visibility="invisible"
|
||||
android:onClick="@{()->viewModel.importFavorites()}"
|
||||
app:icon="@drawable/ic_bookmark"
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">Chaosflix</string>
|
||||
|
||||
<string name="title">title</string>
|
||||
<string name="subtitle">subtitle</string>
|
||||
<string name="thumbnail">thumbnail</string>
|
||||
<string name="card">card</string>
|
||||
<string name="select_option">Select Media Option</string>
|
||||
<string name="search_title">Search</string>
|
||||
|
||||
<string name="download">Download</string>
|
||||
<string name="bookmark">Bookmark</string>
|
||||
|
||||
<string name="play">Play</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="titleimage">TitleImage</string>
|
||||
<string name="update_database">Update Database</string>
|
||||
<string name="search_events">Search Events</string>
|
||||
<string name="search_talks">Search Talks</string>
|
||||
<string name="event_details_image_thumbnail_description">Thumbnail-picture for this event</string>
|
||||
|
||||
<string name="bookmarks">Bookmarks</string>
|
||||
<string name="recordings">Recordings</string>
|
||||
<string name="livestreams">Livestreams</string>
|
||||
<string name="watchlist">Watchlist</string>
|
||||
<string name="continue_watching">Continue Watching</string>
|
||||
<string name="about">About</string>
|
||||
<string name="downloads">Downloads</string>
|
||||
|
||||
<string name="preferences">Preferences</string>
|
||||
<string name="drawer_open">Drawer open</string>
|
||||
<string name="drawer_close">Drawer closed</string>
|
||||
<string name="about_title">Chaosflix</string>
|
||||
<string name="remove_bookmark">Remove Bookmark</string>
|
||||
<string name="delete_local_file">Delete local File</string>
|
||||
<string name="about_voctocat"> The Vocotocat-Logo was designed by Sebastian Morr and is released under CC BY-NC-SA 4.0</string>
|
||||
<string name="showLibs">Libraries we use</string>
|
||||
<string name="about_chaosflix">About Chaosflix</string>
|
||||
<string name="chaosflix_licence">Chaosflix is released under MIT-License.</string>
|
||||
<string name="description">Chaosflix was developed, because the developer was annoyed
|
||||
that there was an app for Apple-TV but not Android- and Fire-TV. So now, after the
|
||||
TV-app there is also one for (android) phones and tablets. Enjoy!</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="reload">Reload</string>
|
||||
<string name="no_livestreams">Currently no livestreams</string>
|
||||
<string name="watch_this">Watch this video from media.ccc.de</string>
|
||||
<string name="related_events">Related Events</string>
|
||||
<string name="about_github">Find the source on Github</string>
|
||||
<string name="about_beta">Become a Beta-Tester</string>
|
||||
<string name="about_twitter">Follow the developer on Twitter</string>
|
||||
<string name="about_playstore">Rate us on Google Play</string>
|
||||
<string name="select_stream">Select Stream</string>
|
||||
<string name="play_button">Play-Button</string>
|
||||
<string name="list_of_events">List of Events</string>
|
||||
<string name="delete_item">Delete Item</string>
|
||||
<string name="import_favorites">Import Favorites</string>
|
||||
<string name="import_activity_label">Fahrplan-Import</string>
|
||||
<string name="select_all">Select all</string>
|
||||
<string name="import_label">Bookmark</string>
|
||||
<string name="empty" />
|
||||
</resources>
|
Loading…
Reference in a new issue