Skip to content

Commit

Permalink
Redo TV Files view to be a stack of folders, similar to phone
Browse files Browse the repository at this point in the history
  • Loading branch information
DSteve595 committed Jan 13, 2017
1 parent bee0765 commit b1e227a
Show file tree
Hide file tree
Showing 17 changed files with 388 additions and 319 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ android {
applicationId 'com.stevenschoen.putionew'
minSdkVersion 19
targetSdkVersion 25
versionCode 111
versionName '4.0.9'
versionCode 112
versionName '4.1-beta1'
multiDexEnabled true
}
buildTypes {
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
<activity
android:name=".tv.TvActivity"
android:label="@string/putio"
android:theme="@style/Theme.Leanback">
android:theme="@style/Theme.Putio.Tv">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

Expand All @@ -196,7 +196,7 @@
<activity
android:name=".tv.TvPlaybackOverlayActivity"
android:label="@string/putio"
android:theme="@style/Theme.Leanback"/>
android:theme="@style/Theme.Putio.Tv"/>
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ void saveTokenFromWeb(final String url) {
private void saveToken(String token) {
sharedPrefs.edit().putString("token", token).commit();
Toast.makeText(this, R.string.loginsuccess, Toast.LENGTH_SHORT).show();
setResult(RESULT_OK);

CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class FolderFragment : FileListFragment<FileListFragment.Callbacks>() {
error.printStackTrace()
Toast.makeText(context, R.string.network_error, Toast.LENGTH_SHORT).show()
})
folderLoader!!.getCachedFile()
folderLoader!!.publishCachedFileIfNeeded()
folderLoader!!.refreshFolder(onlyIfStaleOrEmpty = true)
updateViewState()
}
Expand Down
39 changes: 18 additions & 21 deletions app/src/main/java/com/stevenschoen/putionew/files/FolderLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,36 @@ import java.io.IOException

class FolderLoader(context: Context, private val folder: PutioFile) : PutioBaseLoader(context) {

val diskCache = DiskCache()
val diskCache by lazy { DiskCache() }

private val folderSubject = BehaviorSubject.create<FolderResponse>()
fun folder() = folderSubject.observeOn(AndroidSchedulers.mainThread())

fun getCachedFile() {
Observable.fromCallable {
if (diskCache.isCached(folder.id)) {
return@fromCallable diskCache.getCached(folder.id)
} else {
return@fromCallable null
}
fun publishCachedFileIfNeeded() {
fun isNeeded() = (!folderSubject.hasValue() || !folderSubject.value.fresh)
if (isNeeded()) {
Observable.fromCallable { return@fromCallable if (diskCache.isCached(folder.id)) diskCache.getCached(folder.id) else null }
.subscribeOn(Schedulers.io())
.filter { it != null }
.subscribe({ cachedResponse ->
cachedResponse!!
if (isNeeded()) {
folderSubject.onNext(FolderResponse(false, cachedResponse.parent, cachedResponse.files))
}
}, { error ->
error.printStackTrace()
diskCache.deleteCached(folder.id)
})
}
.filter { it != null }
.subscribeOn(Schedulers.io())
.subscribe({ cachedResponse ->
cachedResponse!!
if (!folderSubject.hasValue() || !folderSubject.value.fresh) {
folderSubject.onNext(FolderResponse(false, cachedResponse.parent, cachedResponse.files))
}
}, { error ->
error.printStackTrace()
diskCache.deleteCached(folder.id)
})
}

var refreshSubscription: Subscription? = null
fun refreshFolder(onlyIfStaleOrEmpty: Boolean = false) {
fun refreshFolder(onlyIfStaleOrEmpty: Boolean = false, cache: Boolean = true) {
if (onlyIfStaleOrEmpty && (hasFresh() || isRefreshing())) return
refreshSubscription?.unsubscribe()
refreshSubscription = api.files(folder.id).subscribe({ response ->
refreshSubscription = null
diskCache.cache(response)
if (cache) diskCache.cache(response)
folderSubject.onNext(FolderResponse(true, response.parent, response.files))
}, { error ->
refreshSubscription = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.NavUtils;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.stevenschoen.putionew.PutioActivity;
import com.stevenschoen.putionew.R;

public class AboutFragment extends Fragment {
Expand Down Expand Up @@ -46,15 +43,4 @@ public void onClick(View v) {

return view;
}

@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case android.R.id.home:
Intent homeIntent = new Intent(getActivity(), PutioActivity.class);
NavUtils.navigateUpTo(getActivity(), homeIntent);
return true;
}
return (super.onOptionsItemSelected(menuItem));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.stevenschoen.putionew.tv

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import com.stevenschoen.putionew.R
import com.stevenschoen.putionew.UIUtils

class HorizontalStackLayout : ViewGroup {

constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

val layerOffset by lazy { resources.getDimensionPixelSize(R.dimen.tv_layer_offset) }
val layerElevation by lazy { resources.getDimension(R.dimen.tv_layer_elevation) }

override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
val childLeft = paddingLeft;
val childTop = paddingTop;
val childRight = measuredWidth - paddingRight;
val childBottom = measuredHeight - paddingBottom;
val childWidth = childRight - childLeft;
val childHeight = childBottom - childTop;

for (i in 0..childCount - 1) {
val child = getChildAt(i)
val offset = (i * layerOffset)
child.measure(MeasureSpec.makeMeasureSpec(childWidth - offset, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY));
child.layout(childLeft + offset, childTop, childRight, childBottom)
if (UIUtils.hasLollipop()) {
child.elevation = (i * layerElevation)
}
}
}

// Hacky, but without it sometimes the d-pad can go to the wrong page and become stuck
override fun focusSearch(focused: View?, direction: Int): View? {
return null
}
}
64 changes: 0 additions & 64 deletions app/src/main/java/com/stevenschoen/putionew/tv/TvActivity.java

This file was deleted.

98 changes: 98 additions & 0 deletions app/src/main/java/com/stevenschoen/putionew/tv/TvActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.stevenschoen.putionew.tv

import android.content.Intent
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentActivity
import com.stevenschoen.putionew.LoginActivity
import com.stevenschoen.putionew.PutioApplication
import com.stevenschoen.putionew.R
import com.stevenschoen.putionew.model.files.PutioFile
import rx.subjects.BehaviorSubject
import java.util.*

class TvActivity : FragmentActivity() {

companion object {
fun makeFolderFragTag(folder: PutioFile) = "folder_${folder.id}"
}

val displayedFolders = ArrayList<PutioFile>()
val folders by lazy { BehaviorSubject.create<List<PutioFile>>(listOf(PutioFile.makeRootFolder(resources))) }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val application = application as PutioApplication
if (application.isLoggedIn) {
init()
} else {
val setupIntent = Intent(this, LoginActivity::class.java)
startActivity(setupIntent)
finish()
return
}
}

fun init() {
setContentView(R.layout.tv_activity)

val stackView = findViewById(R.id.tv_stack) as HorizontalStackLayout

fun addFolder(folder: PutioFile) {
supportFragmentManager.beginTransaction()
.add(R.id.tv_stack, TvFolderFragment.newInstance(this@TvActivity, folder), makeFolderFragTag(folder))
.commitNow()
displayedFolders.add(folder)
}

fun removeLastFolder() {
val lastFolder = displayedFolders.last()
supportFragmentManager.beginTransaction()
.remove(supportFragmentManager.findFragmentByTag(makeFolderFragTag(lastFolder)))
.commitNow()
displayedFolders.removeAt(displayedFolders.lastIndex)
}

addFolder(PutioFile.makeRootFolder(resources))

folders.subscribe { newFolders ->
while (displayedFolders.size > newFolders.size) {
removeLastFolder()
}
for ((index, newFolder) in newFolders.withIndex()) {
if (index <= displayedFolders.lastIndex) {
val displayedFolder = displayedFolders[index]
if (newFolder.id != displayedFolder.id) {
(index..displayedFolders.lastIndex).forEach { removeLastFolder() }
}
} else {
addFolder(newFolder)
}
}
getLastFolderFragment().requestFocusWhenPossible = true
}
}

override fun onAttachFragment(fragment: Fragment) {
super.onAttachFragment(fragment)
if (fragment is TvFolderFragment) {
fragment.onFolderSelected = { folder ->
folders.onNext(folders.value.plus(folder))
}
}
}

fun getLastFolderFragment() = supportFragmentManager.findFragmentByTag(makeFolderFragTag(displayedFolders.last())) as TvFolderFragment

override fun onBackPressed() {
if (displayedFolders.size > 1) {
val lastFolderFragment = supportFragmentManager.findFragmentByTag(makeFolderFragTag(displayedFolders.last()))
if (lastFolderFragment != null && lastFolderFragment is TvFolderFragment) {
folders.onNext(folders.value.dropLast(1))
}
} else {
super.onBackPressed()
}
}
}
Loading

0 comments on commit b1e227a

Please sign in to comment.