Merge branch 'develop' into feature/importFahrplan

This commit is contained in:
Felix 2020-04-04 17:28:00 +02:00
commit 38998661ae
139 changed files with 653 additions and 302 deletions

View file

@ -1,9 +1,16 @@
version: 2 version: 2.1
jobs:
build: references:
working_directory: ~/code
workspace_root: &workspace_root
~/code
container_config: &container_config
docker: docker:
- image: circleci/android:api-28 - image: circleci/android:api-28
working_directory: *workspace_root
environment: environment:
JVM_OPTS: -XX\:MaxHeapSize\=2048m -Xmx1536m JVM_OPTS: -XX\:MaxHeapSize\=2048m -Xmx1536m
LIBS: NoFree LIBS: NoFree
@ -11,88 +18,182 @@ jobs:
APPCENTER_OWNER: nicidienase APPCENTER_OWNER: nicidienase
APPCENTER_GROUP: "Collaborators" APPCENTER_GROUP: "Collaborators"
RELEASENOTES_FILE: "release_notes.txt" RELEASENOTES_FILE: "release_notes.txt"
branches:
only: attach_workspace: &attach_workspace
- master attach_workspace:
- develop at: *workspace_root
- /feature\/.*/
steps: setup_env: &setup_env
- checkout name: Setup environment
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "touch/build.gradle" }}-{{ checksum "leanback/build.gradle" }}-{{ checksum "common/build.gradle" }}
- run:
name: Setup env
command: | command: |
.circleci/setup_env.sh >> $BASH_ENV .circleci/setup_env.sh >> $BASH_ENV
echo "VERSION_CODE_TOUCH=$(.circleci/getVersionCode.sh -t)" >> $BASH_ENV echo "VERSION_CODE_TOUCH=$(.circleci/getVersionCode.sh -t)" >> $BASH_ENV
echo "VERSION_CODE_LEANBACK=$(.circleci/getVersionCode.sh -l)" >> $BASH_ENV echo "VERSION_CODE_LEANBACK=$(.circleci/getVersionCode.sh -l)" >> $BASH_ENV
# . $BASH_ENV
# echo "STAGE=${STAGE}" general_cache_key: &general_cache_key
# echo "VERSION_NAME=${VERSION_NAME}" key: app-{{ checksum ".circleci/config.yml" }}-{{ checksum "gradle.properties" }}-{{ checksum "build.gradle" }}-{{ checksum "touch/build.gradle" }}-{{ checksum "leanback/build.gradle" }}-{{ checksum "common/build.gradle" }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}
# echo "VersionCode: $(.circleci/getVersionCode.sh -t)"
# echo "BUILD_TYPE_LOWER=${BUILD_TYPE_LOWER}" jobs:
# echo "STAGE_LOWER=${STAGE_LOWER}"
# echo "LIBS_LOWER=${LIBS_LOWER}" build:
<<: *container_config
steps:
- checkout
- restore_cache:
<<: *general_cache_key
- run:
<<: *setup_env
- run: - run:
name: Download Dependencies name: Download Dependencies
command: ./gradlew $SIGN_CONFIG androidDependencies
- run:
name: ktlint
command: | command: |
./gradlew $SIGN_CONFIG --continue \ ./gradlew $KEY_CONFIG $SIGN_CONFIG \
common:ktlint${STAGE}${LIBS}${BUILD_TYPE}Check \ -PversionCode=$VERSION_CODE_TOUCH \
touch:ktlint${STAGE}${LIBS}${BUILD_TYPE}Check \ -PversionName=${VERSION_NAME} \
leanback:ktlint${STAGE}${LIBS}${BUILD_TYPE}Check androidDependencies
- run: - run:
name: Build Touch name: Build Touch
command: | command: |
./gradlew $SIGN_CONFIG \ ./gradlew $SIGN_CONFIG $KEY_CONFIG \
-PversionCode=$VERSION_CODE_TOUCH \ -PversionCode=$VERSION_CODE_TOUCH \
-PversionName=${VERSION_NAME} \ -PversionName=${VERSION_NAME} \
touch:assemble${STAGE_LOWER}${LIBS}${BUILD_TYPE} touch:assemble${STAGE_LOWER}${LIBS}${BUILD_TYPE}
- run:
name: Build Leanback
command: |
./gradlew $SIGN_CONFIG \
-PversionCode=$VERSION_CODE_LEANBACK \
-PversionName=${VERSION_NAME} \
leanback:assemble${STAGE_LOWER}${LIBS}${BUILD_TYPE}
- run:
name: Test
command: |
./gradlew $SIGN_CONFIG --continue \
common:test${STAGE}${LIBS}${BUILD_TYPE}UnitTest \
common:lint${STAGE}${LIBS}${BUILD_TYPE} \
touch:test${STAGE}${LIBS}${BUILD_TYPE}UnitTest \
touch:lint${STAGE}${LIBS}${BUILD_TYPE} \
leanback:test${STAGE}${LIBS}${BUILD_TYPE}UnitTest \
leanback:lint${STAGE}${LIBS}${BUILD_TYPE}
- store_artifacts:
path: common/build/outputs
destination: common-reports
- store_artifacts: - store_artifacts:
path: touch/build/outputs path: touch/build/outputs
destination: touch destination: touch
- store_artifacts:
path: touch/build/outputs - run:
destination: touch-reports name: Build Leanback
command: |
./gradlew $KEY_CONFIG $SIGN_CONFIG \
-PversionCode=$VERSION_CODE_LEANBACK \
-PversionName=${VERSION_NAME} \
leanback:assemble${STAGE_LOWER}${LIBS}${BUILD_TYPE}
- store_artifacts: - store_artifacts:
path: leanback/build/outputs path: leanback/build/outputs
destination: leanback destination: leanback
- save_cache:
<<: *general_cache_key
paths:
- "~/.gradle"
- "~/.m2"
- "/opt/android-sdk-linux/licenses/"
- persist_to_workspace:
root: *workspace_root
paths:
- .
check:
<<: *container_config
parallelism: 1 #4
steps:
- *attach_workspace
- restore_cache:
<<: *general_cache_key
- run:
<<: *setup_env
- run:
name: Lint Common
command: |
./gradlew $KEY_CONFIG \
-PversionCode=$VERSION_CODE_LEANBACK \
-PversionName=${VERSION_NAME} \
common:lint${STAGE}${LIBS}${BUILD_TYPE}
- run:
name: Lint Touch
command: |
./gradlew $KEY_CONFIG \
-PversionCode=$VERSION_CODE_LEANBACK \
-PversionName=${VERSION_NAME} \
touch:lint${STAGE}${LIBS}${BUILD_TYPE}
- run:
name: Lint Leanback
command: |
./gradlew $KEY_CONFIG \
-PversionCode=$VERSION_CODE_LEANBACK \
-PversionName=${VERSION_NAME} \
leanback:lint${STAGE}${LIBS}${BUILD_TYPE} \
- run:
name: Ktlint
command: |
./gradlew $KEY_CONFIG \
-PversionCode=$VERSION_CODE_LEANBACK \
-PversionName=${VERSION_NAME} \
ktlintCheck
- store_artifacts: - store_artifacts:
path: leanback/build/reports path: common/build/reports/
destination: leanback-reports destination: lint_reports/common/
- store_artifacts: - store_artifacts:
path: common/build/reports/ktlint/ path: touch/build/reports/
destination: ktlint-reports destination: lint_reports/touch/
- store_artifacts:
path: leanback/build/reports/
destination: lint_reports/leanback/
test:
<<: *container_config
steps:
- *attach_workspace
- restore_cache:
<<: *general_cache_key
- run:
<<: *setup_env
- run:
name: Test Common
command: |
./gradlew $KEY_CONFIG common:test${STAGE}${LIBS}${BUILD_TYPE}UnitTest
- run:
name: Test Touch
command: |
./gradlew $KEY_CONFIG \
-PversionCode=$VERSION_CODE_TOUCH \
-PversionName=${VERSION_NAME} \
touch:test${STAGE}${LIBS}${BUILD_TYPE}UnitTest
- run:
name: Test Leanback
command: |
./gradlew $KEY_CONFIG \
-PversionCode=$VERSION_CODE_LEANBACK \
-PversionName=${VERSION_NAME} \
leanback:test${STAGE}${LIBS}${BUILD_TYPE}UnitTest \
- store_test_results: - store_test_results:
path: common/build/test-results path: common/build/test-results
- store_test_results: - store_test_results:
path: touch/build/test-results path: touch/build/test-results
- store_test_results: - store_test_results:
path: leanback/build/test-results path: leanback/build/test-results
publish-appcenter:
<<: *container_config
steps:
- *attach_workspace
- restore_cache:
<<: *general_cache_key
- run: - run:
name: Appcenter Upload <<: *setup_env
- run:
name: Touch Appcenter Upload
command: | command: |
git log --format="%h %s" master..HEAD > $RELEASENOTES_FILE git log --format="%h %s" master..HEAD > $RELEASENOTES_FILE
.circleci/appCenterUpload.sh \ .circleci/appCenterUpload.sh \
@ -104,7 +205,71 @@ jobs:
"touch/build/outputs/mapping/${STAGE_LOWER}${LIBS}/${BUILD_TYPE_LOWER}/mapping.txt" \ "touch/build/outputs/mapping/${STAGE_LOWER}${LIBS}/${BUILD_TYPE_LOWER}/mapping.txt" \
"$VERSION_CODE_TOUCH" \ "$VERSION_CODE_TOUCH" \
"$VERSION_NAME" "$VERSION_NAME"
- save_cache:
paths: - run:
- ~/.gradle name: Leanback Appcenter Upload
key: jars-{{ checksum "build.gradle" }}-{{ checksum "touch/build.gradle" }}-{{ checksum "leanback/build.gradle" }}-{{ checksum "common/build.gradle" }} command: |
git log --format="%h %s" master..HEAD > $RELEASENOTES_FILE
.circleci/appCenterUpload.sh \
$APPCENTER_OWNER \
$APPCENTER_TOKEN \
"leanback/build/outputs/apk/${STAGE_LOWER}${LIBS}/${BUILD_TYPE_LOWER}/touch-${STAGE_LOWER}-${LIBS_LOWER}-${BUILD_TYPE_LOWER}.apk" \
$RELEASENOTES_FILE \
$APPCENTER_GROUP \
"leanback/build/outputs/mapping/${STAGE_LOWER}${LIBS}/${BUILD_TYPE_LOWER}/mapping.txt" \
"$VERSION_CODE_LEANBACK" \
"$VERSION_NAME"
publish-play:
<<: *container_config
steps:
- *attach_workspace
- restore_cache:
<<: *general_cache_key
- run:
<<: *setup_env
- run:
name: Setup environment
command: .circleci/setup_env.sh >> $BASH_ENV
- run:
name: Touch Playstore Upload
command: |
echo "$ENCODED_PLAY_CREDENTIALS" | base64 --decode > ./chaosflix-d1d09f33cbb2.json
./gradlew $KEY_CONFIG \
-PversionCode=$VERSION_CODE_TOUCH \
-PversionName=${VERSION_NAME} \
touch:publishApk
workflows:
version: 2
build_test_publish:
jobs:
- build
- check:
requires:
- build
- test:
requires:
- build
- publish-appcenter:
requires:
- test
- check
filters:
branches:
only:
- master
- develop
- publish-play:
requires:
- test
- check
filters:
branches:
only:
- master

View file

@ -15,9 +15,10 @@ echo "export LIBS_LOWER=\"$(tr '[:upper:]' '[:lower:]' <<< ${LIBS:0:1})${LIBS:1}
echo "$ENCODED_KEYSTORE" | base64 --decode > ${HOME}/code/keystore.jks echo "$ENCODED_KEYSTORE" | base64 --decode > ${HOME}/code/keystore.jks
KEYSTORE=${HOME}/code/keystore.jks KEYSTORE=${HOME}/code/keystore.jks
echo "export SIGN_CONFIG=\"-PchaosflixKeystore=$KEYSTORE\ echo "export KEY_CONFIG=\"-PappcenterId=$APPCENTER_ID\
-PchaosflixStorePassword=$KEYSTORE_PASSWORD\
-PchaosflixKeyName=$KEY_NAME\
-PchaosflixKeyPassword=$KEYSTORE_PASSWORD\
-PappcenterId=$APPCENTER_ID\
-PappcenterDevId=$APPCENTER_DEV_ID\"" -PappcenterDevId=$APPCENTER_DEV_ID\""
echo "export SIGN_CONFIG=\"-PchaosflixKeystore=$KEYSTORE \
-PchaosflixStorePassword=$KEYSTORE_PASSWORD \
-PchaosflixKeyName=$KEY_NAME \
-PchaosflixKeyPassword=$KEYSTORE_PASSWORD\""

3
.gitignore vendored
View file

@ -62,4 +62,5 @@ freeline_project_description.json
common/release common/release
touch/release touch/release
leanback/release leanback/release
chaosflix-d1d09f33cbb2.json

View file

@ -11,7 +11,7 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jlleitschuh.gradle:ktlint-gradle:8.0.0" classpath "org.jlleitschuh.gradle:ktlint-gradle:9.1.1"
classpath "de.mannodermaus.gradle.plugins:android-junit5:1.5.2.0" classpath "de.mannodermaus.gradle.plugins:android-junit5:1.5.2.0"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
@ -31,9 +31,6 @@ allprojects {
ext{ ext{
touchVersionCode = 1
leanbackVersionCode = 1
minSDK = 22 minSDK = 22
targetSDK = 28 targetSDK = 28
compileSdkVersion = 28 compileSdkVersion = 28
@ -51,4 +48,3 @@ apply plugin: "org.jlleitschuh.gradle.ktlint-idea"
subprojects { subprojects {
apply plugin: "org.jlleitschuh.gradle.ktlint" apply plugin: "org.jlleitschuh.gradle.ktlint"
} }

View file

@ -32,6 +32,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
lintOptions {
abortOnError false
}
buildTypes { buildTypes {
debug { debug {
minifyEnabled false minifyEnabled false
@ -48,43 +52,59 @@ android {
productFlavors { productFlavors {
prod { prod {
dimension "stage" dimension "stage"
if (project.hasProperty('appcenterId')){
buildConfigField "String", "APPCENTER_ID", "$appcenterId"
} else {
buildConfigField "String", "APPCENTER_ID", "\"\""
}
} }
dev { dev {
dimension "stage" dimension "stage"
if (project.hasProperty('appcenterDevId')){
buildConfigField "String", "APPCENTER_ID", "$appcenterDevId"
} else {
buildConfigField "String", "APPCENTER_ID", "\"\""
}
} }
mock { mock {
dimension "stage" dimension "stage"
if (project.hasProperty('appcenterDevId')){
buildConfigField "String", "APPCENTER_ID", "$appcenterDevId"
} else {
buildConfigField "String", "APPCENTER_ID", "\"\""
}
buildConfigField "String", "STREAMING_API_BASE_URL", "\"https://gist.githubusercontent.com\"" buildConfigField "String", "STREAMING_API_BASE_URL", "\"https://gist.githubusercontent.com\""
buildConfigField "String", "STREAMING_API_OFFERS_PATH", "\"/NiciDieNase/1ca017f180242f0ee683a1f592efc4ed/raw/0104592b57f4b29863fd0684a510462af276f30e/example_streams_v2.json\"" buildConfigField "String", "STREAMING_API_OFFERS_PATH", "\"/NiciDieNase/1ca017f180242f0ee683a1f592efc4ed/raw/0104592b57f4b29863fd0684a510462af276f30e/example_streams_v2.json\""
} }
free { free {
dimension "libs" dimension "libs"
ext {
prod = null
dev = null
mock = null
}
} }
noFree{ noFree{
dimension "libs" dimension "libs"
ext {
if(project.hasProperty("appcenterId")){
prod = appcenterId
} else {
prod = null
println "AppcenterId not set"
}
if(project.hasProperty("appcenterDevId")){
dev = appcenterDevId
mock = appcenterDevId
} else {
dev = null
mock = null
println "AppcenterId not set"
}
}
} }
} }
libraryVariants.all { variant ->
def flavors = variant.productFlavors
// flavorDimensions "stage" -> 0, "libs" -> 1
def stage = flavors[0]
def libs = flavors[1]
variant.buildConfigField "String", "APPCENTER_ID", "${libs[stage.name]}"
}
variantFilter { variant -> variantFilter { variant ->
def names = variant.flavors*.name
if (name.contains("prod") && name.contains("Debug")){ if (name.contains("prod") && name.contains("Debug")){
setIgnore(true) setIgnore(true)
} }

View file

@ -6,4 +6,4 @@ object BuildTypeInit : ChaosflixInitializer {
override fun init(chaosflixApplication: ChaosflixApplication) { override fun init(chaosflixApplication: ChaosflixApplication) {
Stetho.initializeWithDefaults(chaosflixApplication) Stetho.initializeWithDefaults(chaosflixApplication)
} }
} }

View file

@ -3,4 +3,4 @@ import de.nicidienase.chaosflix.ChaosflixInitializer
object LibsInit : ChaosflixInitializer { object LibsInit : ChaosflixInitializer {
override fun init(chaosflixApplication: ChaosflixApplication) {} override fun init(chaosflixApplication: ChaosflixApplication) {}
} }

View file

@ -25,4 +25,4 @@ class ChaosflixLoadingSpinner(context: Context, attributeSet: AttributeSet) : Im
anim.repeatCount = Animation.INFINITE anim.repeatCount = Animation.INFINITE
animation = anim animation = anim
} }
} }

View file

@ -8,4 +8,4 @@ interface AnalyticsWrapper {
fun startAnalytics() fun startAnalytics()
fun stopAnalytics() fun stopAnalytics()
} }

View file

@ -1,22 +1,22 @@
package de.nicidienase.chaosflix.common package de.nicidienase.chaosflix.common
import androidx.sqlite.db.SupportSQLiteDatabase import android.content.Context
import androidx.room.Database import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters import androidx.room.TypeConverters
import androidx.room.migration.Migration import androidx.room.migration.Migration
import android.content.Context import androidx.sqlite.db.SupportSQLiteDatabase
import de.nicidienase.chaosflix.common.mediadata.entities.Converters import de.nicidienase.chaosflix.common.mediadata.entities.Converters
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceDao import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceDao
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceGroup import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceGroup
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceGroupDao import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceGroupDao
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.EventDao
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.EventDao
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Recording import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Recording
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.RelatedEvent
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.RecordingDao import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.RecordingDao
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.RelatedEvent
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.RelatedEventDao import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.RelatedEventDao
import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEvent import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEvent
import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEventDao import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEventDao
@ -101,4 +101,4 @@ abstract class ChaosflixDatabase : RoomDatabase() {
} }
} }
} }
} }

View file

@ -112,4 +112,4 @@ object ChaosflixUtil {
private const val HD_WEBM = "HD-video/webm" private const val HD_WEBM = "HD-video/webm"
private const val SD_MP4 = "SD-video/mp4" private const val SD_MP4 = "SD-video/mp4"
private const val SD_WEBM = "SD-video/webm" private const val SD_WEBM = "SD-video/webm"
} }

View file

@ -2,9 +2,9 @@ package de.nicidienase.chaosflix.common
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import androidx.fragment.app.Fragment
import androidx.core.content.ContextCompat
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
fun androidx.fragment.app.Fragment.checkPermission(permission: String, requestCode: Int, action: () -> Unit) { fun androidx.fragment.app.Fragment.checkPermission(permission: String, requestCode: Int, action: () -> Unit) {
if (ContextCompat.checkSelfPermission(requireContext(), permission) if (ContextCompat.checkSelfPermission(requireContext(), permission)
@ -25,4 +25,4 @@ fun AppCompatActivity.checkPermission(permission: String, requestCode: Int, acti
} else { } else {
action() action()
} }
} }

View file

@ -22,13 +22,13 @@ import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEvent
import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEventDao import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEventDao
import de.nicidienase.chaosflix.common.util.LiveEvent import de.nicidienase.chaosflix.common.util.LiveEvent
import de.nicidienase.chaosflix.common.viewmodel.DetailsViewModel import de.nicidienase.chaosflix.common.viewmodel.DetailsViewModel
import java.io.File
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.File
class OfflineItemManager( class OfflineItemManager(
context: Context, context: Context,
@ -212,4 +212,4 @@ class OfflineItemManager(
enum class State { enum class State {
Downloading, Done, PermissionRequired Downloading, Done, PermissionRequired
} }
} }

View file

@ -27,4 +27,4 @@ class PreferencesManager(val sharedPref: SharedPreferences) {
private val keyAnalyticsDisabled = "disable_analytics" private val keyAnalyticsDisabled = "disable_analytics"
private val keyDownloadFolder = "download_folder" private val keyDownloadFolder = "download_folder"
} }
} }

View file

@ -8,4 +8,4 @@ class ResourcesFacade(context: Context) {
private val resources: Resources = context.applicationContext.resources private val resources: Resources = context.applicationContext.resources
fun getString(@StringRes id: Int, vararg any: Any): String = resources.getString(id, any) fun getString(@StringRes id: Int, vararg any: Any): String = resources.getString(id, any)
} }

View file

@ -46,4 +46,4 @@ open class SingletonHolder2<out T, in A, in B>(creator: (A, B) -> T) {
} }
} }
} }
} }

View file

@ -23,12 +23,12 @@ import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem
import de.nicidienase.chaosflix.common.util.ConferenceUtil import de.nicidienase.chaosflix.common.util.ConferenceUtil
import de.nicidienase.chaosflix.common.util.LiveEvent import de.nicidienase.chaosflix.common.util.LiveEvent
import de.nicidienase.chaosflix.common.util.SingleLiveEvent import de.nicidienase.chaosflix.common.util.SingleLiveEvent
import java.io.IOException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.Response import retrofit2.Response
import java.io.IOException
class MediaRepository( class MediaRepository(
private val recordingApi: RecordingService, private val recordingApi: RecordingService,
@ -217,6 +217,12 @@ class MediaRepository(
return event return event
} }
suspend fun findConferenceForUri(data: Uri): Conference? {
val conference =
conferenceDao.findConferenceByAcronymSuspend(data.lastPathSegment)
return conference
}
suspend fun findEventByTitle(title: String): Event? { suspend fun findEventByTitle(title: String): Event? {
var event: Event? = eventDao.findEventByTitleSuspend(title) var event: Event? = eventDao.findEventByTitleSuspend(title)
if (event == null) { if (event == null) {
@ -273,4 +279,4 @@ class MediaRepository(
enum class State { enum class State {
DONE, RUNNING DONE, RUNNING
} }
} }

View file

@ -3,4 +3,4 @@ package de.nicidienase.chaosflix.common.mediadata.entities.recording
import androidx.annotation.Keep import androidx.annotation.Keep
@Keep @Keep
class EventsResponse(var events: List<EventDto>) class EventsResponse(var events: List<EventDto>)

View file

@ -33,4 +33,4 @@ data class RelatedEventDto(
return arrayOfNulls(size) return arrayOfNulls(size)
} }
} }
} }

View file

@ -37,4 +37,4 @@ abstract class BaseDao<in T> {
} }
protected abstract suspend fun updateOrInsertInternal(item: T) protected abstract suspend fun updateOrInsertInternal(item: T)
} }

View file

@ -1,11 +1,11 @@
package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence
import android.os.Parcel
import android.os.Parcelable
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import android.os.Parcel
import android.os.Parcelable
import de.nicidienase.chaosflix.common.mediadata.entities.recording.ConferenceDto import de.nicidienase.chaosflix.common.mediadata.entities.recording.ConferenceDto
@Entity(tableName = "conference", @Entity(tableName = "conference",
@ -97,4 +97,4 @@ data class Conference(
return arrayOfNulls(size) return arrayOfNulls(size)
} }
} }
} }

View file

@ -1,11 +1,11 @@
package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence
import android.os.Parcel
import android.os.Parcelable
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import android.os.Parcel
import android.os.Parcelable
@Entity( @Entity(
tableName = "conference_group", tableName = "conference_group",
@ -45,4 +45,4 @@ data class ConferenceGroup(
return arrayOfNulls(size) return arrayOfNulls(size)
} }
} }
} }

View file

@ -31,4 +31,4 @@ abstract class ConferenceGroupDao : BaseDao<ConferenceGroup>() {
} }
} }
} }
} }

View file

@ -1,14 +1,14 @@
package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence
import android.os.Parcel
import android.os.Parcelable
import android.text.Html
import android.text.Spanned
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import android.os.Parcel
import android.os.Parcelable
import android.text.Html
import android.text.Spanned
import de.nicidienase.chaosflix.common.mediadata.entities.recording.EventDto import de.nicidienase.chaosflix.common.mediadata.entities.recording.EventDto
@Entity(tableName = "event", @Entity(tableName = "event",
@ -164,4 +164,4 @@ data class Event(
return arrayOfNulls(size) return arrayOfNulls(size)
} }
} }
} }

View file

@ -80,4 +80,4 @@ abstract class EventDao : BaseDao<Event>() {
} }
} }
} }
} }

View file

@ -1,12 +1,12 @@
package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence
import android.os.Parcel
import android.os.Parcelable
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import android.os.Parcel
import android.os.Parcelable
import de.nicidienase.chaosflix.common.mediadata.entities.recording.RecordingDto import de.nicidienase.chaosflix.common.mediadata.entities.recording.RecordingDto
@Entity(tableName = "recording", @Entity(tableName = "recording",
@ -118,4 +118,4 @@ data class Recording(
return arrayOfNulls(size) return arrayOfNulls(size)
} }
} }
} }

View file

@ -44,4 +44,4 @@ abstract class RecordingDao : BaseDao<Recording>() {
} }
} }
} }
} }

View file

@ -1,12 +1,12 @@
package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence package de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence
import android.os.Parcel
import android.os.Parcelable
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import android.os.Parcel
import android.os.Parcelable
import de.nicidienase.chaosflix.common.mediadata.entities.recording.RelatedEventDto import de.nicidienase.chaosflix.common.mediadata.entities.recording.RelatedEventDto
@Entity(tableName = "related", @Entity(tableName = "related",
@ -58,4 +58,4 @@ data class RelatedEvent(
return arrayOfNulls(size) return arrayOfNulls(size)
} }
} }
} }

View file

@ -85,4 +85,4 @@ data class Room(
return dummy return dummy
} }
} }
} }

View file

@ -6,13 +6,13 @@ import com.google.gson.Gson
import de.nicidienase.chaosflix.BuildConfig import de.nicidienase.chaosflix.BuildConfig
import de.nicidienase.chaosflix.R import de.nicidienase.chaosflix.R
import de.nicidienase.chaosflix.common.SingletonHolder2 import de.nicidienase.chaosflix.common.SingletonHolder2
import java.io.File
import java.util.concurrent.TimeUnit
import okhttp3.Cache import okhttp3.Cache
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit
class ApiFactory private constructor(res: Resources, cache: File) { class ApiFactory private constructor(res: Resources, cache: File) {
@ -63,4 +63,4 @@ class ApiFactory private constructor(res: Resources, cache: File) {
return "chaosflix/$versionName $osVersion ($device)" return "chaosflix/$versionName $osVersion ($device)"
} }
} }
} }

View file

@ -44,4 +44,4 @@ interface RecordingService {
@GET("public/events/{guid}") @GET("public/events/{guid}")
suspend fun getEventByGUIDSuspending(@Path("guid") guid: String): EventDto? suspend fun getEventByGUIDSuspending(@Path("guid") guid: String): EventDto?
} }

View file

@ -1,12 +1,12 @@
package de.nicidienase.chaosflix.common.userdata.entities.download package de.nicidienase.chaosflix.common.userdata.entities.download
import android.os.Parcel
import android.os.Parcelable
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import android.os.Parcel
import android.os.Parcelable
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Recording import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Recording
@ -56,4 +56,4 @@ data class OfflineEvent(
return arrayOfNulls(size) return arrayOfNulls(size)
} }
} }
} }

View file

@ -40,4 +40,4 @@ interface OfflineEventDao {
@Query("SELECT o.event_guid,o.recording_id,o.download_reference,o.local_path,e.title,e.subtitle,e.length,e.thumbUrl FROM offline_event o JOIN event e WHERE o.event_guid = e.guid") @Query("SELECT o.event_guid,o.recording_id,o.download_reference,o.local_path,e.title,e.subtitle,e.length,e.thumbUrl FROM offline_event o JOIN event e WHERE o.event_guid = e.guid")
fun getOfflineEventsDisplay(): LiveData<List<OfflineEventView>> fun getOfflineEventsDisplay(): LiveData<List<OfflineEventView>>
} }

View file

@ -1,7 +1,7 @@
package de.nicidienase.chaosflix.common.userdata.entities.download package de.nicidienase.chaosflix.common.userdata.entities.download
import androidx.room.ColumnInfo
import androidx.annotation.Keep import androidx.annotation.Keep
import androidx.room.ColumnInfo
@Keep @Keep
data class OfflineEventView( data class OfflineEventView(
@ -13,4 +13,4 @@ data class OfflineEventView(
@ColumnInfo(name = "subtitle") var subtitle: String?, @ColumnInfo(name = "subtitle") var subtitle: String?,
@ColumnInfo(name = "length") val length: Long, @ColumnInfo(name = "length") val length: Long,
@ColumnInfo(name = "thumbUrl") var thumbUrl: String @ColumnInfo(name = "thumbUrl") var thumbUrl: String
) )

View file

@ -25,4 +25,4 @@ interface PlaybackProgressDao {
@Query("DELETE from playback_progress WHERE event_guid = :guid") @Query("DELETE from playback_progress WHERE event_guid = :guid")
fun deleteItem(guid: String) fun deleteItem(guid: String)
} }

View file

@ -2,10 +2,10 @@ package de.nicidienase.chaosflix.common.userdata.entities.watchlist
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Query
import androidx.room.OnConflictStrategy
import androidx.room.Insert
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.BaseDao import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.BaseDao
@Dao @Dao
@ -45,4 +45,4 @@ abstract class WatchlistItemDao : BaseDao<WatchlistItem>() {
} }
} }
} }
} }

View file

@ -41,4 +41,4 @@ object ConferenceUtil {
"fiffkon", "fiffkon",
"cryptocon" "cryptocon"
) )
} }

View file

@ -16,4 +16,4 @@ class LiveDataMerger<T, U, R> {
} }
return result return result
} }
} }

View file

@ -4,4 +4,4 @@ class LiveEvent<T, U, V>(
val state: T, val state: T,
val data: U? = null, val data: U? = null,
val error: V? = null val error: V? = null
) )

View file

@ -16,12 +16,11 @@
package de.nicidienase.chaosflix.common.util package de.nicidienase.chaosflix.common.util
import android.util.Log
import androidx.annotation.MainThread
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.annotation.MainThread
import android.util.Log
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
/** /**
@ -73,4 +72,4 @@ class SingleLiveEvent<T> : MutableLiveData<T>() {
private val TAG = "SingleLiveEvent" private val TAG = "SingleLiveEvent"
} }
} }

View file

@ -11,8 +11,8 @@ import de.nicidienase.chaosflix.common.PreferencesManager
import de.nicidienase.chaosflix.common.ResourcesFacade import de.nicidienase.chaosflix.common.ResourcesFacade
import de.nicidienase.chaosflix.common.mediadata.MediaRepository import de.nicidienase.chaosflix.common.mediadata.MediaRepository
import de.nicidienase.chaosflix.common.mediadata.StreamingRepository import de.nicidienase.chaosflix.common.mediadata.StreamingRepository
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceGroup
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceGroup
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.LiveConference import de.nicidienase.chaosflix.common.mediadata.entities.streaming.LiveConference
import de.nicidienase.chaosflix.common.util.LiveDataMerger import de.nicidienase.chaosflix.common.util.LiveDataMerger

View file

@ -14,9 +14,9 @@ import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.
import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem
import de.nicidienase.chaosflix.common.util.LiveEvent import de.nicidienase.chaosflix.common.util.LiveEvent
import de.nicidienase.chaosflix.common.util.SingleLiveEvent import de.nicidienase.chaosflix.common.util.SingleLiveEvent
import java.io.File
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File
class DetailsViewModel( class DetailsViewModel(
private val database: ChaosflixDatabase, private val database: ChaosflixDatabase,

View file

@ -5,9 +5,9 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import de.nicidienase.chaosflix.common.ChaosflixDatabase import de.nicidienase.chaosflix.common.ChaosflixDatabase
import de.nicidienase.chaosflix.common.userdata.entities.progress.PlaybackProgress import de.nicidienase.chaosflix.common.userdata.entities.progress.PlaybackProgress
import java.util.Date
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.Date
class PlayerViewModel(val database: ChaosflixDatabase) : ViewModel() { class PlayerViewModel(val database: ChaosflixDatabase) : ViewModel() {

View file

@ -11,13 +11,13 @@ import de.nicidienase.chaosflix.common.mediadata.MediaRepository
import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem
import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItemDao import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItemDao
import de.nicidienase.chaosflix.common.util.LiveEvent import de.nicidienase.chaosflix.common.util.LiveEvent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.BufferedReader import java.io.BufferedReader
import java.io.BufferedWriter import java.io.BufferedWriter
import java.io.File import java.io.File
import java.io.FileReader import java.io.FileReader
import java.io.FileWriter import java.io.FileWriter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class PreferencesViewModel( class PreferencesViewModel(
private val mediaRepository: MediaRepository, private val mediaRepository: MediaRepository,
@ -94,4 +94,4 @@ class PreferencesViewModel(
private val TAG = PreferencesViewModel::class.java.simpleName private val TAG = PreferencesViewModel::class.java.simpleName
private const val FAVORITES_FILENAME = "chaosflix_favorites.json" private const val FAVORITES_FILENAME = "chaosflix_favorites.json"
} }
} }

View file

@ -7,15 +7,15 @@ import de.nicidienase.chaosflix.common.mediadata.MediaRepository
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.util.LiveEvent import de.nicidienase.chaosflix.common.util.LiveEvent
import de.nicidienase.chaosflix.common.util.SingleLiveEvent import de.nicidienase.chaosflix.common.util.SingleLiveEvent
import java.lang.Exception
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.lang.Exception
class SplashViewModel( class SplashViewModel(
private val mediaRepository: MediaRepository private val mediaRepository: MediaRepository
) : ViewModel() { ) : ViewModel() {
val state: SingleLiveEvent<LiveEvent<State, Event, Exception>> = SingleLiveEvent() val state: SingleLiveEvent<LiveEvent<State, Any, Exception>> = SingleLiveEvent()
fun findEventForUri(data: Uri) = viewModelScope.launch(Dispatchers.IO) { fun findEventForUri(data: Uri) = viewModelScope.launch(Dispatchers.IO) {
try { try {
@ -30,8 +30,21 @@ class SplashViewModel(
} }
} }
fun findConferenceForUri(data: Uri) = viewModelScope.launch(Dispatchers.IO) {
try {
val conference = mediaRepository.findConferenceForUri(data)
if (conference != null) {
state.postValue(LiveEvent(State.FOUND, conference))
} else {
state.postValue(LiveEvent(State.NOT_FOUND))
}
} catch (ex: Exception) {
state.postValue(LiveEvent(State.NOT_FOUND, error = ex))
}
}
enum class State { enum class State {
FOUND, FOUND,
NOT_FOUND NOT_FOUND
} }
} }

View file

@ -13,4 +13,4 @@ object LibsInit : ChaosflixInitializer {
AnalyticsWrapperImpl.init(chaosflixApplication) AnalyticsWrapperImpl.init(chaosflixApplication)
} }
} }
} }

View file

@ -21,11 +21,11 @@ object AnalyticsWrapperImpl : AnalyticsWrapper {
override fun startAnalytics() { override fun startAnalytics() {
Analytics.setEnabled(true) Analytics.setEnabled(true)
// Crashes.setEnabled(true) Crashes.setEnabled(true)
} }
override fun stopAnalytics() { override fun stopAnalytics() {
Analytics.setEnabled(false) Analytics.setEnabled(false)
// Crashes.setEnabled(false) Crashes.setEnabled(false)
} }
} }

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="privacy_policy">Chaosflix does not collect or transmit any personalized data.\n\nFor statistical and troubleshooting purposes an anonymous ID, type, version and language of the device, service life and crash logs are collected using Microsoft Visual Studio App Center.</string> <string name="privacy_policy">Chaosflix does not collect or transmit any personalized data.\n\nFor statistical and troubleshooting purposes an anonymous ID, type, version and language of the device, service life and crash logs are collected using Microsoft Visual Studio App Center.\nThis can be disable in preferences.</string>
</resources> </resources>

View file

@ -3,4 +3,4 @@ import de.nicidienase.chaosflix.ChaosflixInitializer
object StageInit : ChaosflixInitializer { object StageInit : ChaosflixInitializer {
override fun init(chaosflixApplication: ChaosflixApplication) {} override fun init(chaosflixApplication: ChaosflixApplication) {}
} }

View file

@ -30,4 +30,4 @@ class ConferencesWrapperTest {
) )
assert(wrapper.conferencesMap.keys.size == 1) assert(wrapper.conferencesMap.keys.size == 1)
} }
} }

View file

@ -1,6 +1,7 @@
#Sun Nov 10 22:16:34 CET 2019 #Mon Feb 03 20:13:07 CET 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
distributionSha256Sum=10065868c78f1207afb3a92176f99a37d753a513dff453abb6b5cceda4058cda

View file

@ -1,7 +1,10 @@
apply plugin: 'com.android.application' plugins {
apply plugin: 'kotlin-android' id 'com.android.application'
apply plugin: 'kotlin-kapt' id 'kotlin-android'
apply plugin: 'kotlin-android-extensions' id 'kotlin-kapt'
id 'kotlin-android-extensions'
id 'com.github.triplet.play' version '2.6.2'
}
String appName = "Chaosflix" String appName = "Chaosflix"
String versionString = new File("versionfile").text.trim() String versionString = new File("versionfile").text.trim()
@ -16,7 +19,7 @@ android {
minSdkVersion rootProject.ext.minSDK minSdkVersion rootProject.ext.minSDK
targetSdkVersion rootProject.ext.targetSDK targetSdkVersion rootProject.ext.targetSDK
// odd for touch, even for leanback // odd for touch, even for leanback
versionCode rootProject.ext.leanbackVersionCode versionCode 1
versionName versionString versionName versionString
if(project.hasProperty("versionCode")){ if(project.hasProperty("versionCode")){
versionCode = project.property("versionCode") as int versionCode = project.property("versionCode") as int
@ -101,6 +104,11 @@ android {
lintOptions.abortOnError = false lintOptions.abortOnError = false
dataBinding.enabled = true dataBinding.enabled = true
buildToolsVersion rootProject.ext.buildToolsVersion buildToolsVersion rootProject.ext.buildToolsVersion
playConfigs {
prodNoFree {
enabled = true
}
}
} }
configurations { configurations {
@ -127,3 +135,10 @@ dependencies {
androidTestImplementation 'org.hamcrest:hamcrest-library:1.3' androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.6.0' androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.6.0'
} }
play {
serviceAccountCredentials = file("../chaosflix-d1d09f33cbb2.json")
track = "Alpha"
enabled = false
}

View file

@ -1,13 +1,13 @@
package de.nicidienase.chaosflix.leanback package de.nicidienase.chaosflix.leanback
import android.os.Bundle import android.os.Bundle
import androidx.leanback.app.ErrorSupportFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.leanback.app.ErrorSupportFragment
class BrowseErrorFragment : ErrorSupportFragment() { class BrowseErrorFragment : ErrorSupportFragment() {
private var spinnerFragment: SpinnerFragment? = null private var spinnerFragment: SpinnerFragment? = null

View file

@ -18,4 +18,4 @@ class ChaosflixEventAdapter(presenter: Presenter) : ArrayObjectAdapter(presenter
-1 -1
} }
} }
} }

View file

@ -24,4 +24,4 @@ object DiffCallbacks {
return oldItem.updatedAt == newItem.updatedAt return oldItem.updatedAt == newItem.updatedAt
} }
} }
} }

View file

@ -1,12 +1,12 @@
package de.nicidienase.chaosflix.leanback package de.nicidienase.chaosflix.leanback
import android.content.Context import android.content.Context
import androidx.leanback.widget.Presenter
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.leanback.widget.Presenter
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Room import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Room
import de.nicidienase.chaosflix.leanback.databinding.DetailViewBinding import de.nicidienase.chaosflix.leanback.databinding.DetailViewBinding

View file

@ -1,8 +1,7 @@
package de.nicidienase.chaosflix.leanback.conferences package de.nicidienase.chaosflix.leanback.conferences
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.leanback.app.BrowseSupportFragment import androidx.leanback.app.BrowseSupportFragment
import androidx.leanback.widget.ArrayObjectAdapter import androidx.leanback.widget.ArrayObjectAdapter
import androidx.leanback.widget.DividerRow import androidx.leanback.widget.DividerRow
@ -11,7 +10,8 @@ import androidx.leanback.widget.ListRow
import androidx.leanback.widget.ListRowPresenter import androidx.leanback.widget.ListRowPresenter
import androidx.leanback.widget.Row import androidx.leanback.widget.Row
import androidx.leanback.widget.SectionRow import androidx.leanback.widget.SectionRow
import android.util.Log import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import de.nicidienase.chaosflix.common.mediadata.MediaRepository import de.nicidienase.chaosflix.common.mediadata.MediaRepository
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceGroup import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.ConferenceGroup

View file

@ -7,9 +7,9 @@ import android.graphics.Color
import android.graphics.Paint import android.graphics.Paint
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
import android.os.Build import android.os.Build
import android.util.Log
import androidx.leanback.media.PlaybackGlue import androidx.leanback.media.PlaybackGlue
import androidx.leanback.widget.PlaybackSeekDataProvider import androidx.leanback.widget.PlaybackSeekDataProvider
import android.util.Log
import de.nicidienase.chaosflix.common.mediadata.network.ApiFactory import de.nicidienase.chaosflix.common.mediadata.network.ApiFactory
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -212,4 +212,4 @@ class ChaosflixSeekDataProvider(
} }
} }
} }
} }

View file

@ -3,9 +3,8 @@ package de.nicidienase.chaosflix.leanback.detail
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import android.view.WindowManager import android.view.WindowManager
import androidx.fragment.app.FragmentActivity
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Room import de.nicidienase.chaosflix.common.mediadata.entities.streaming.Room
import de.nicidienase.chaosflix.leanback.R import de.nicidienase.chaosflix.leanback.R

View file

@ -1,8 +1,6 @@
package de.nicidienase.chaosflix.leanback.detail package de.nicidienase.chaosflix.leanback.detail
import android.app.AlertDialog import android.app.AlertDialog
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
@ -12,6 +10,10 @@ import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.text.TextUtils
import android.util.Log
import android.view.View
import androidx.core.content.ContextCompat
import androidx.leanback.app.DetailsSupportFragment import androidx.leanback.app.DetailsSupportFragment
import androidx.leanback.app.DetailsSupportFragmentBackgroundController import androidx.leanback.app.DetailsSupportFragmentBackgroundController
import androidx.leanback.widget.Action import androidx.leanback.widget.Action
@ -24,10 +26,8 @@ import androidx.leanback.widget.HeaderItem
import androidx.leanback.widget.ListRow import androidx.leanback.widget.ListRow
import androidx.leanback.widget.ListRowPresenter import androidx.leanback.widget.ListRowPresenter
import androidx.leanback.widget.OnActionClickedListener import androidx.leanback.widget.OnActionClickedListener
import androidx.core.content.ContextCompat import androidx.lifecycle.Observer
import android.text.TextUtils import androidx.lifecycle.ViewModelProviders
import android.util.Log
import android.view.View
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.SimpleTarget
@ -405,4 +405,4 @@ class EventDetailsFragment : DetailsSupportFragment() {
builder.create().show() builder.create().show()
} }
} }
} }

View file

@ -1,11 +1,11 @@
package de.nicidienase.chaosflix.leanback.events package de.nicidienase.chaosflix.leanback.events
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import de.nicidienase.chaosflix.common.mediadata.MediaRepository import de.nicidienase.chaosflix.common.mediadata.MediaRepository
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event

View file

@ -3,6 +3,9 @@ package de.nicidienase.chaosflix.leanback.events
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.util.DisplayMetrics
import android.util.Log
import androidx.core.content.ContextCompat
import androidx.leanback.app.BackgroundManager import androidx.leanback.app.BackgroundManager
import androidx.leanback.app.VerticalGridSupportFragment import androidx.leanback.app.VerticalGridSupportFragment
import androidx.leanback.widget.ArrayObjectAdapter import androidx.leanback.widget.ArrayObjectAdapter
@ -12,9 +15,6 @@ import androidx.leanback.widget.Presenter
import androidx.leanback.widget.Row import androidx.leanback.widget.Row
import androidx.leanback.widget.RowPresenter import androidx.leanback.widget.RowPresenter
import androidx.leanback.widget.VerticalGridPresenter import androidx.leanback.widget.VerticalGridPresenter
import androidx.core.content.ContextCompat
import android.util.DisplayMetrics
import android.util.Log
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.SimpleTarget

View file

@ -3,6 +3,9 @@ package de.nicidienase.chaosflix.leanback.events
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.util.DisplayMetrics
import android.util.Log
import androidx.core.content.ContextCompat
import androidx.leanback.app.BackgroundManager import androidx.leanback.app.BackgroundManager
import androidx.leanback.app.BrowseSupportFragment import androidx.leanback.app.BrowseSupportFragment
import androidx.leanback.widget.ArrayObjectAdapter import androidx.leanback.widget.ArrayObjectAdapter
@ -13,9 +16,6 @@ import androidx.leanback.widget.OnItemViewSelectedListener
import androidx.leanback.widget.Presenter import androidx.leanback.widget.Presenter
import androidx.leanback.widget.Row import androidx.leanback.widget.Row
import androidx.leanback.widget.RowPresenter import androidx.leanback.widget.RowPresenter
import androidx.core.content.ContextCompat
import android.util.DisplayMetrics
import android.util.Log
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.SimpleTarget

View file

@ -1,7 +1,10 @@
apply plugin: 'com.android.application' plugins {
apply plugin: 'kotlin-android' id 'com.android.application'
apply plugin: 'kotlin-kapt' id 'kotlin-android'
apply plugin: 'kotlin-android-extensions' id 'kotlin-kapt'
id 'kotlin-android-extensions'
id 'com.github.triplet.play' version '2.6.2'
}
String appName = "Chaosflix" String appName = "Chaosflix"
String versionString = new File("versionfile").text.trim() String versionString = new File("versionfile").text.trim()
@ -17,7 +20,7 @@ android {
targetSdkVersion rootProject.ext.targetSDK targetSdkVersion rootProject.ext.targetSDK
manifestPlaceholders = [label: appName] manifestPlaceholders = [label: appName]
// odd for touch, even for leanback // odd for touch, even for leanback
versionCode rootProject.ext.touchVersionCode versionCode 1
versionName versionString versionName versionString
if(project.hasProperty("versionCode")){ if(project.hasProperty("versionCode")){
@ -57,6 +60,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro' 'proguard-rules.pro'
if (project.hasProperty("chaosflixKeystore") && file(chaosflixKeystore).exists() && file(chaosflixKeystore).isFile()) { if (project.hasProperty("chaosflixKeystore") && file(chaosflixKeystore).exists() && file(chaosflixKeystore).isFile()) {
signingConfig signingConfigs.release signingConfig signingConfigs.release
} }
} }
@ -110,6 +114,12 @@ android {
lintOptions.abortOnError false lintOptions.abortOnError false
dataBinding.enabled = true dataBinding.enabled = true
testOptions.unitTests.includeAndroidResources = true testOptions.unitTests.includeAndroidResources = true
playConfigs {
prodNoFreeRelease {
enabled = true
}
}
} }
configurations { configurations {
@ -153,4 +163,12 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0', { androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations' exclude group: 'com.android.support', module: 'support-annotations'
} }
} }
play {
serviceAccountCredentials = file("../chaosflix-d1d09f33cbb2.json")
track = "alpha"
releaseStatus = "draft"
enabled = false
artifactDir = file("build/outputs/apk/prodNoFree/release/touch-prod-noFree-release.apk")
}

View file

@ -4,9 +4,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import de.nicidienase.chaosflix.common.ChaosflixDatabase import de.nicidienase.chaosflix.common.ChaosflixDatabase
import de.nicidienase.chaosflix.common.userdata.entities.progress.PlaybackProgress import de.nicidienase.chaosflix.common.userdata.entities.progress.PlaybackProgress
import java.util.Date
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import java.util.Date
/** /**
* Created by felix on 31.10.17. * Created by felix on 31.10.17.

View file

@ -8,6 +8,7 @@ import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.StreamUrl import de.nicidienase.chaosflix.common.mediadata.entities.streaming.StreamUrl
import de.nicidienase.chaosflix.touch.browse.streaming.StreamingItem import de.nicidienase.chaosflix.touch.browse.streaming.StreamingItem
@SuppressWarnings("unused")
class CastService(activity: Activity, withMiniController: Boolean = true) { class CastService(activity: Activity, withMiniController: Boolean = true) {
val connected: Boolean = false val connected: Boolean = false
@ -27,4 +28,4 @@ class CastService(activity: Activity, withMiniController: Boolean = true) {
companion object { companion object {
val TAG = CastService::class.java.simpleName val TAG = CastService::class.java.simpleName
} }
} }

View file

@ -0,0 +1,14 @@
Schaue Aufzeichnungen und Streams von media.ccc.de auf deinem Smartphone, Tablet oder AndroidTV-Gerät.
Features:
<ul>
<li>Livestreams</li>
<li>Talks als Lesezeichen Speichern</li>
<li>Talks zum offline Schauen herunterladen</li>
</ul>
Chromecast-Unterstützung fehlt leider in der Version auf F-Droid, da hierfür unfreie Bibliotheken nötig sind.
Die Version für Fernseher (AndroidTV und FireTV) ist zur Zeit nicht auf F-Droid
Bugreports, Verbesserungsvorschläge, etc. sind willkommen: https://github.com/NiciDieNase/chaosflix/issues

View file

@ -0,0 +1,14 @@
Watch streams and recordings from media.ccc.de on your phone or tablet.
Features:
<ul>
<li>Livestreams</li>
<li>Bookmarking Talks</li>
<li>Download Talks for offline viewing</li>
</ul>
Chromecast support is not available for the version on F-Droid, since it requires non-free libraries.
There is also a version for TVs (AndroidTV and FireTV) which is current not on F-Droid.
Suggestions, Bugreports, etc. are welcome on https://github.com/NiciDieNase/chaosflix/issues

View file

@ -37,6 +37,10 @@
android:scheme="https" android:scheme="https"
android:host="media.ccc.de" android:host="media.ccc.de"
android:pathPrefix="/v/"/> android:pathPrefix="/v/"/>
<data
android:scheme="https"
android:host="media.ccc.de"
android:pathPrefix="/c/"/>
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".browse.BrowseActivity"> <activity android:name=".browse.BrowseActivity">

View file

@ -1,12 +1,12 @@
package de.nicidienase.chaosflix.touch package de.nicidienase.chaosflix.touch
import androidx.databinding.BindingAdapter
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
@BindingAdapter("bind:imageUrl") @BindingAdapter("imageUrl")
fun loadImage(imageView: ImageView, url: String?) { fun loadImage(imageView: ImageView, url: String?) {
if (url == null) return if (url == null) return
Glide.with(imageView.context) Glide.with(imageView.context)
@ -15,7 +15,7 @@ fun loadImage(imageView: ImageView, url: String?) {
.into(imageView) .into(imageView)
} }
@BindingAdapter("bind:time") @BindingAdapter("time")
fun setDuration(textView: TextView, duration: Long) { fun setDuration(textView: TextView, duration: Long) {
textView.text = String.format("%d:%02d:%02d", duration / 3600, (duration % 3600) / 60, duration % 60) textView.text = String.format("%d:%02d:%02d", duration / 3600, (duration % 3600) / 60, duration % 60)
} }

View file

@ -4,4 +4,4 @@ import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.
interface OnEventSelectedListener { interface OnEventSelectedListener {
fun onEventSelected(event: Event) fun onEventSelected(event: Event)
} }

View file

@ -6,10 +6,12 @@ import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.viewmodel.SplashViewModel import de.nicidienase.chaosflix.common.viewmodel.SplashViewModel
import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory
import de.nicidienase.chaosflix.touch.browse.BrowseActivity import de.nicidienase.chaosflix.touch.browse.BrowseActivity
import de.nicidienase.chaosflix.touch.browse.eventslist.EventsListActivity
import de.nicidienase.chaosflix.touch.eventdetails.EventDetailsActivity import de.nicidienase.chaosflix.touch.eventdetails.EventDetailsActivity
class SplashActivity : AppCompatActivity() { class SplashActivity : AppCompatActivity() {
@ -37,11 +39,10 @@ class SplashActivity : AppCompatActivity() {
viewModel.state.observe(this, Observer { viewModel.state.observe(this, Observer {
when (it.state) { when (it.state) {
SplashViewModel.State.FOUND -> { SplashViewModel.State.FOUND -> {
val event = it.data when (val item = it.data) {
if (event != null) { is Event -> goToEvent(item)
goToEvent(event) is Conference -> goToConference(item)
} else { else -> goToOverview()
goToOverview()
} }
} }
SplashViewModel.State.NOT_FOUND -> { SplashViewModel.State.NOT_FOUND -> {
@ -51,7 +52,10 @@ class SplashActivity : AppCompatActivity() {
}) })
if (data != null) { if (data != null) {
viewModel.findEventForUri(data) when (data.pathSegments[0]) {
"v" -> viewModel.findEventForUri(data)
"c" -> viewModel.findConferenceForUri(data)
}
} else { } else {
goToOverview() goToOverview()
} }
@ -66,4 +70,9 @@ class SplashActivity : AppCompatActivity() {
EventDetailsActivity.launch(this, event) EventDetailsActivity.launch(this, event)
finish() finish()
} }
}
private fun goToConference(conference: Conference) {
EventsListActivity.start(this, conference)
finish()
}
}

View file

@ -1,10 +1,10 @@
package de.nicidienase.chaosflix.touch.about package de.nicidienase.chaosflix.touch.about
import androidx.databinding.DataBindingUtil
import android.os.Bundle import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.view.View import androidx.databinding.DataBindingUtil
import de.nicidienase.chaosflix.touch.R import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.touch.databinding.ActivityAboutBinding import de.nicidienase.chaosflix.touch.databinding.ActivityAboutBinding
import mehdi.sakout.aboutpage.AboutPage import mehdi.sakout.aboutpage.AboutPage

View file

@ -1,10 +1,10 @@
package de.nicidienase.chaosflix.touch.about package de.nicidienase.chaosflix.touch.about
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.DialogFragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import com.mikepenz.aboutlibraries.LibsBuilder import com.mikepenz.aboutlibraries.LibsBuilder
import com.mikepenz.aboutlibraries.ui.LibsSupportFragment import com.mikepenz.aboutlibraries.ui.LibsSupportFragment
import de.nicidienase.chaosflix.touch.R import de.nicidienase.chaosflix.touch.R
@ -23,4 +23,4 @@ class LibsFragment : androidx.fragment.app.DialogFragment() {
.withFields(R.string::class.java.fields) .withFields(R.string::class.java.fields)
.supportFragment() .supportFragment()
} }
} }

View file

@ -1,28 +1,28 @@
package de.nicidienase.chaosflix.touch.browse package de.nicidienase.chaosflix.touch.browse
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
import androidx.databinding.DataBindingUtil
import android.os.Bundle import android.os.Bundle
import android.os.PersistableBundle import android.os.PersistableBundle
import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.Snackbar
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import android.transition.TransitionInflater import android.transition.TransitionInflater
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.Snackbar
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.StreamUrl import de.nicidienase.chaosflix.common.mediadata.entities.streaming.StreamUrl

View file

@ -1,11 +1,11 @@
package de.nicidienase.chaosflix.touch.browse package de.nicidienase.chaosflix.touch.browse
import androidx.lifecycle.ViewModelProviders
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment import android.view.View
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import android.view.View import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import de.nicidienase.chaosflix.common.viewmodel.BrowseViewModel import de.nicidienase.chaosflix.common.viewmodel.BrowseViewModel
import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory

View file

@ -1,8 +1,8 @@
package de.nicidienase.chaosflix.touch.browse.adapters package de.nicidienase.chaosflix.touch.browse.adapters
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.touch.browse.ConferencesTabBrowseFragment import de.nicidienase.chaosflix.touch.browse.ConferencesTabBrowseFragment
import de.nicidienase.chaosflix.touch.databinding.ItemConferenceCardviewBinding import de.nicidienase.chaosflix.touch.databinding.ItemConferenceCardviewBinding

View file

@ -1,9 +1,9 @@
package de.nicidienase.chaosflix.touch.browse.adapters package de.nicidienase.chaosflix.touch.browse.adapters
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.RecyclerView
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.touch.databinding.ItemEventCardviewBinding import de.nicidienase.chaosflix.touch.databinding.ItemEventCardviewBinding

View file

@ -1,8 +1,8 @@
package de.nicidienase.chaosflix.touch.browse.adapters package de.nicidienase.chaosflix.touch.browse.adapters
import androidx.recyclerview.widget.RecyclerView
import android.widget.Filter import android.widget.Filter
import android.widget.Filterable import android.widget.Filterable
import androidx.recyclerview.widget.RecyclerView
import java.util.Collections import java.util.Collections
abstract class ItemRecyclerViewAdapter<T, VH : RecyclerView.ViewHolder?> : abstract class ItemRecyclerViewAdapter<T, VH : RecyclerView.ViewHolder?> :

View file

@ -1,13 +1,13 @@
package de.nicidienase.chaosflix.touch.browse.download package de.nicidienase.chaosflix.touch.browse.download
import androidx.lifecycle.Observer
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import de.nicidienase.chaosflix.touch.R import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.touch.browse.BrowseFragment import de.nicidienase.chaosflix.touch.browse.BrowseFragment
import de.nicidienase.chaosflix.touch.databinding.FragmentDownloadsBinding import de.nicidienase.chaosflix.touch.databinding.FragmentDownloadsBinding
@ -84,4 +84,4 @@ class DownloadsListFragment : BrowseFragment() {
return fragment return fragment
} }
} }
} }

View file

@ -1,15 +1,15 @@
package de.nicidienase.chaosflix.touch.browse.download package de.nicidienase.chaosflix.touch.browse.download
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import de.nicidienase.chaosflix.common.OfflineItemManager import de.nicidienase.chaosflix.common.OfflineItemManager
import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEventView import de.nicidienase.chaosflix.common.userdata.entities.download.OfflineEventView
import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.touch.databinding.ItemOfflineEventBinding import de.nicidienase.chaosflix.touch.databinding.ItemOfflineEventBinding
class OfflineEventAdapter( class OfflineEventAdapter(
@ -58,4 +58,4 @@ class OfflineEventAdapter(
inner class ViewHolder(val binding: ItemOfflineEventBinding, val view: View) : RecyclerView.ViewHolder(view) { inner class ViewHolder(val binding: ItemOfflineEventBinding, val view: View) : RecyclerView.ViewHolder(view) {
val thumbnail = binding.imageView val thumbnail = binding.imageView
} }
} }

View file

@ -3,12 +3,12 @@ package de.nicidienase.chaosflix.touch.browse.eventslist
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu import android.view.Menu
import de.nicidienase.chaosflix.touch.R import androidx.appcompat.app.AppCompatActivity
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Conference
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.touch.OnEventSelectedListener import de.nicidienase.chaosflix.touch.OnEventSelectedListener
import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.touch.browse.cast.CastService import de.nicidienase.chaosflix.touch.browse.cast.CastService
import de.nicidienase.chaosflix.touch.eventdetails.EventDetailsActivity import de.nicidienase.chaosflix.touch.eventdetails.EventDetailsActivity

View file

@ -1,9 +1,9 @@
package de.nicidienase.chaosflix.touch.browse.streaming package de.nicidienase.chaosflix.touch.browse.streaming
import androidx.recyclerview.widget.RecyclerView
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.LiveConference import de.nicidienase.chaosflix.common.mediadata.entities.streaming.LiveConference

View file

@ -1,15 +1,15 @@
package de.nicidienase.chaosflix.touch.browse.streaming package de.nicidienase.chaosflix.touch.browse.streaming
import androidx.lifecycle.Observer
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import com.google.android.material.snackbar.Snackbar
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import de.nicidienase.chaosflix.touch.R import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.touch.browse.BrowseFragment import de.nicidienase.chaosflix.touch.browse.BrowseFragment
import de.nicidienase.chaosflix.touch.databinding.FragmentLivestreamsBinding import de.nicidienase.chaosflix.touch.databinding.FragmentLivestreamsBinding
@ -98,4 +98,4 @@ class LivestreamListFragment : BrowseFragment() {
return fragment return fragment
} }
} }
} }

View file

@ -8,4 +8,4 @@ data class StreamingItem(
val conference: LiveConference, val conference: LiveConference,
val group: Group, val group: Group,
val room: Room val room: Room
) )

View file

@ -1,8 +1,6 @@
package de.nicidienase.chaosflix.touch.eventdetails package de.nicidienase.chaosflix.touch.eventdetails
import android.Manifest import android.Manifest
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
@ -10,10 +8,12 @@ import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import com.google.android.material.snackbar.Snackbar import android.view.Menu
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.view.Menu import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.google.android.material.snackbar.Snackbar
import de.nicidienase.chaosflix.common.ChaosflixUtil import de.nicidienase.chaosflix.common.ChaosflixUtil
import de.nicidienase.chaosflix.common.OfflineItemManager import de.nicidienase.chaosflix.common.OfflineItemManager
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event

View file

@ -1,17 +1,9 @@
package de.nicidienase.chaosflix.touch.eventdetails package de.nicidienase.chaosflix.touch.eventdetails
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.snackbar.Snackbar
import androidx.fragment.app.Fragment
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
@ -19,16 +11,24 @@ import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import de.nicidienase.chaosflix.touch.R import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.snackbar.Snackbar
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem import de.nicidienase.chaosflix.common.userdata.entities.watchlist.WatchlistItem
import de.nicidienase.chaosflix.common.viewmodel.DetailsViewModel import de.nicidienase.chaosflix.common.viewmodel.DetailsViewModel
import de.nicidienase.chaosflix.touch.databinding.FragmentEventDetailsBinding
import de.nicidienase.chaosflix.touch.OnEventSelectedListener
import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory
import de.nicidienase.chaosflix.touch.OnEventSelectedListener
import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.touch.browse.adapters.EventRecyclerViewAdapter import de.nicidienase.chaosflix.touch.browse.adapters.EventRecyclerViewAdapter
import de.nicidienase.chaosflix.touch.databinding.FragmentEventDetailsBinding
class EventDetailsFragment : androidx.fragment.app.Fragment() { class EventDetailsFragment : androidx.fragment.app.Fragment() {

View file

@ -64,7 +64,7 @@ public class ExoPlayerFragment extends Fragment implements PlayerEventListener.P
private PlayerViewModel viewModel; private PlayerViewModel viewModel;
private PlaybackItem item; private PlaybackItem item;
FragmentExoPlayerBinding binding; private FragmentExoPlayerBinding binding;
public ExoPlayerFragment() { public ExoPlayerFragment() {
} }
@ -87,12 +87,12 @@ public class ExoPlayerFragment extends Fragment implements PlayerEventListener.P
playbackState = savedInstanceState.getBoolean(PLAYBACK_STATE, true); playbackState = savedInstanceState.getBoolean(PLAYBACK_STATE, true);
} }
viewModel = ViewModelProviders.of(this, ViewModelFactory.Companion.getInstance(requireContext())).get(PlayerViewModel.class);
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_exo_player, container, false); binding = DataBindingUtil.inflate(inflater, R.layout.fragment_exo_player, container, false);
viewModel = ViewModelProviders.of(this, ViewModelFactory.Companion.getInstance(requireContext())).get(PlayerViewModel.class);
Toolbar toolbar = binding.getRoot().findViewById(R.id.toolbar); Toolbar toolbar = binding.getRoot().findViewById(R.id.toolbar);
toolbar.setTitle(item.getTitle()); toolbar.setTitle(item.getTitle());
@ -170,8 +170,11 @@ public class ExoPlayerFragment extends Fragment implements PlayerEventListener.P
AdaptiveTrackSelection.Factory trackSelectorFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER); AdaptiveTrackSelection.Factory trackSelectorFactory = new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);
DefaultTrackSelector trackSelector = new DefaultTrackSelector(trackSelectorFactory); DefaultTrackSelector trackSelector = new DefaultTrackSelector(trackSelectorFactory);
LoadControl loadControl = new DefaultLoadControl(); DefaultRenderersFactory renderersFactory
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(getContext(), null, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF); = new DefaultRenderersFactory(
getContext(),
null,
DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
exoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector); exoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector);

View file

@ -31,4 +31,4 @@ data class PlaybackItem(val title: String, val subtitle: String, val eventGuid:
return arrayOfNulls(size) return arrayOfNulls(size)
} }
} }
} }

View file

@ -3,13 +3,13 @@ package de.nicidienase.chaosflix.touch.playback
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import de.nicidienase.chaosflix.touch.R import androidx.appcompat.app.AppCompatActivity
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Event
import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Recording import de.nicidienase.chaosflix.common.mediadata.entities.recording.persistence.Recording
import de.nicidienase.chaosflix.common.mediadata.entities.streaming.StreamUrl import de.nicidienase.chaosflix.common.mediadata.entities.streaming.StreamUrl
import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.touch.browse.cast.CastService import de.nicidienase.chaosflix.touch.browse.cast.CastService
class PlayerActivity : AppCompatActivity() { class PlayerActivity : AppCompatActivity() {

View file

@ -1,8 +1,8 @@
package de.nicidienase.chaosflix.touch.settings package de.nicidienase.chaosflix.touch.settings
import androidx.databinding.DataBindingUtil
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import de.nicidienase.chaosflix.touch.R import de.nicidienase.chaosflix.touch.R
import de.nicidienase.chaosflix.touch.databinding.ActivitySettingsBinding import de.nicidienase.chaosflix.touch.databinding.ActivitySettingsBinding
@ -15,4 +15,4 @@ class SettingsActivity : AppCompatActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setTitle(R.string.settings) supportActionBar?.setTitle(R.string.settings)
} }
} }

View file

@ -1,15 +1,15 @@
package de.nicidienase.chaosflix.touch.settings package de.nicidienase.chaosflix.touch.settings
import android.Manifest import android.Manifest
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import android.preference.PreferenceManager
import com.google.android.material.snackbar.Snackbar import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.snackbar.Snackbar
import de.nicidienase.chaosflix.R import de.nicidienase.chaosflix.R
import de.nicidienase.chaosflix.common.checkPermission import de.nicidienase.chaosflix.common.checkPermission
import de.nicidienase.chaosflix.common.viewmodel.PreferencesViewModel import de.nicidienase.chaosflix.common.viewmodel.PreferencesViewModel
@ -177,4 +177,4 @@ class SettingsFragment : PreferenceFragmentCompat() {
return fragment return fragment
} }
} }
} }

View file

@ -0,0 +1 @@
chaosflix@nicidienase.de

View file

@ -0,0 +1 @@
https://github.com/NiciDieNase/chaosflix

View file

@ -0,0 +1 @@
en-US

View file

@ -0,0 +1,11 @@
Schaue Aufzeichnungen und Streams von media.ccc.de auf deinem Smartphone, Tablet oder AndroidTV-Gerät.
Features:
<ul>
<li>Livestreams</li>
<li>Talks als Lesezeichen Speichern</li>
<li>Talks zum offline Schauen herunterladen</li>
<li>Chromecast-Unterstützung</li>
</ul>
Bugreports, Verbesserungsvorschläge, etc. sind willkommen: https://github.com/NiciDieNase/chaosflix/issues

View file

@ -0,0 +1 @@
Schaue Aufzeichnungen und Streams von media.ccc.de

View file

@ -0,0 +1,11 @@
Watch streams and recordings from media.ccc.de on your phone, tablet or AndroidTV-device
Features:
<ul>
<li>Livestreams</li>
<li>Bookmarking Talks</li>
<li>Download Talks for offline viewing</li>
<li>Watch on Chromecast</li>
</ul>
Suggestions, Bugreports, etc. are welcome on https://github.com/NiciDieNase/chaosflix/issues

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Some files were not shown because too many files have changed in this diff Show more