improved launch presentations

This commit is contained in:
Mariotaku Lee 2017-09-08 13:48:29 +08:00
parent 812a44512c
commit d2fccb6fc7
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
6 changed files with 172 additions and 23 deletions

View File

@ -143,8 +143,29 @@ public class LaunchPresentation {
@JsonField(name = "url")
String url;
@JsonField(name = "density")
float density;
@JsonField(name = "width")
int width;
@JsonField(name = "height")
int height;
public String getUrl() {
return url;
}
public float getDensity() {
return density;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
}

View File

@ -32,6 +32,7 @@ import android.support.annotation.StyleRes
import android.support.v4.view.ViewCompat
import android.support.v7.app.TwilightManagerAccessor
import android.view.View
import android.view.View.MeasureSpec
import android.widget.Toast
import com.bumptech.glide.Glide
import com.bumptech.glide.Priority
@ -54,6 +55,7 @@ import org.mariotaku.twidere.constant.lastLaunchTimeKey
import org.mariotaku.twidere.constant.promotionsEnabledKey
import org.mariotaku.twidere.constant.themeColorKey
import org.mariotaku.twidere.constant.themeKey
import org.mariotaku.twidere.extension.model.displayingScore
import org.mariotaku.twidere.extension.model.hasInvalidAccount
import org.mariotaku.twidere.extension.model.shouldShow
import org.mariotaku.twidere.model.presentation.LaunchPresentation
@ -138,10 +140,10 @@ open class MainActivity : ChameleonActivity(), IBaseActivity<MainActivity> {
}
ViewCompat.setOnApplyWindowInsetsListener(main) lambda@ { _, insets ->
main.setPadding(0, 0, 0, insets.systemWindowInsetBottom)
main.setPadding(0, 0, insets.systemWindowInsetRight,
insets.systemWindowInsetBottom)
controlOverlay.setPadding(insets.systemWindowInsetLeft, insets.systemWindowInsetTop,
insets.systemWindowInsetRight, 0)
controlOverlay.setPadding(0, insets.systemWindowInsetTop, 0, 0)
return@lambda insets.consumeSystemWindowInsets()
}
ViewSupport.setOutlineProvider(skipPresentation, ViewOutlineProviderCompat.BACKGROUND)
@ -163,10 +165,9 @@ open class MainActivity : ChameleonActivity(), IBaseActivity<MainActivity> {
}
val presentation = jsonCache.getList(RefreshLaunchPresentationsTask.JSON_CACHE_KEY,
LaunchPresentation::class.java)?.firstOrNull {
it.shouldShow()
it.shouldShow(this)
}
if (presentation != null) {
displayPresentation(presentation)
if (presentation != null && displayPresentation(presentation)) {
launchLater()
} else {
launchDirectly()
@ -225,12 +226,24 @@ open class MainActivity : ChameleonActivity(), IBaseActivity<MainActivity> {
isNightBackup = nightState
}
private fun displayPresentation(presentation: LaunchPresentation) {
private fun displayPresentation(presentation: LaunchPresentation): Boolean {
skipPresentation.visibility = View.VISIBLE
controlOverlay.tag = presentation
Glide.with(this).load(presentation.images.first().url)
val dm = resources.displayMetrics
main.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels,
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dm.heightPixels,
MeasureSpec.EXACTLY))
val width = presentationView.measuredWidth
val height = presentationView.measuredHeight
val images = presentation.images.sortedByDescending { it.displayingScore(dm.density, width, height) }
val image = images.firstOrNull() ?: return false
Glide.with(this).load(image.url)
.priority(Priority.HIGH)
.into(presentationView)
return true
}
private fun launchDirectly() {

View File

@ -19,17 +19,16 @@
package org.mariotaku.twidere.extension.model
import android.content.Context
import android.support.v4.os.LocaleListCompat
import org.mariotaku.ktextension.localesCompat
import org.mariotaku.twidere.model.presentation.LaunchPresentation
import java.util.*
/**
* Created by mariotaku on 2017/8/20.
*/
fun LaunchPresentation.shouldShow(): Boolean {
fun LaunchPresentation.shouldShow(context: Context): Boolean {
// Check language
val locale = Locale.getDefault()
if (locales != null && locales.none { it.matches(locale) }) {
val userLocales = context.resources.configuration.localesCompat
if (locales != null && locales.none { it.matchesAny(userLocales) }) {
return false
}
// Check date/time
@ -53,4 +52,34 @@ fun LaunchPresentation.Locale.matches(locale: Locale): Boolean {
return locale.country.isNullOrEmpty()
}
return country == locale.country
}
}
fun LaunchPresentation.Locale.matchesAny(locales: LocaleListCompat): Boolean {
return (0 until locales.size()).any { matches(locales[it]) }
}
fun LaunchPresentation.Image.displayingScore(viewDensity: Float, viewWidth: Int,
viewHeight: Int): Int {
if (viewWidth == 0 || viewHeight == 0) return 0
var score = 0
// Compute size scores
score += when {
viewWidth == width && viewHeight <= height -> 100
viewHeight == height && viewWidth <= width -> 100
viewWidth < width && viewHeight < height -> {
val diffW = (width / viewWidth.toFloat() - 1).coerceAtMost(0.5f)
val diffH = (height / viewHeight.toFloat() - 1).coerceAtMost(0.5f)
100 - Math.round(diffH * 100) - Math.round(diffW * 100)
}
else -> {
val diffW = (width / viewWidth.toFloat() - 1).coerceAtMost(0.5f)
val diffH = (height / viewHeight.toFloat() - 1).coerceAtMost(0.5f)
100 - Math.round(diffH * 50) - Math.round(diffW * 50)
}
}
if (this.density != 0f) {
score += 100 - Math.round(Math.abs(this.density / viewDensity - 1).coerceAtMost(1f))
}
return score
}

View File

@ -22,6 +22,7 @@ package org.mariotaku.twidere.task.filter
import android.content.Context
import org.mariotaku.restfu.annotation.method.GET
import org.mariotaku.restfu.http.HttpRequest
import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.model.presentation.LaunchPresentation
import org.mariotaku.twidere.task.BaseAbstractTask
import org.mariotaku.twidere.util.JsonSerializer
@ -33,10 +34,14 @@ import java.io.IOException
*/
class RefreshLaunchPresentationsTask(context: Context) : BaseAbstractTask<Unit?, Boolean, (Boolean) -> Unit>(context) {
override fun doLongOperation(params: Unit?): Boolean {
val request = HttpRequest.Builder()
.method(GET.METHOD)
.url("https://twidere.mariotaku.org/assets/data/launch_presentations.json")
.build()
val builder = HttpRequest.Builder()
builder.method(GET.METHOD)
if (BuildConfig.DEBUG) {
builder.url("https://twidere.mariotaku.org/assets/data/launch_presentations_debug.json")
} else {
builder.url("https://twidere.mariotaku.org/assets/data/launch_presentations.json")
}
val request = builder.build()
try {
val presentations = restHttpClient.newCall(request).execute().use {
if (!it.isSuccessful) return@use null

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/presentationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/logoContainer"
android:layout_toStartOf="@+id/logoContainer"
android:scaleType="centerCrop"
tools:ignore="ContentDescription"/>
<LinearLayout
android:id="@+id/logoContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:gravity="center"
android:minWidth="108dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/appIcon"
android:layout_width="48dp"
android:layout_height="48dp"
tools:ignore="ContentDescription"
tools:src="@mipmap/ic_launcher"/>
</LinearLayout>
<FrameLayout
android:id="@+id/controlOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignEnd="@+id/presentationView"
android:layout_alignRight="@+id/presentationView">
<Button
android:id="@+id/skipPresentation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|end"
android:layout_marginEnd="@dimen/element_spacing_large"
android:layout_marginRight="@dimen/element_spacing_large"
android:layout_marginTop="@dimen/element_spacing_large"
android:background="@drawable/bg_btn_launch_presentation_skip"
android:minHeight="36dp"
android:minWidth="56dp"
android:text="@string/action_skip"
android:textColor="@android:color/white"
android:visibility="gone"
tools:visibility="visible"/>
</FrameLayout>
</RelativeLayout>

View File

@ -47,8 +47,8 @@
android:id="@+id/appIcon"
android:layout_width="48dp"
android:layout_height="48dp"
tools:src="@mipmap/ic_launcher"
tools:ignore="ContentDescription"/>
tools:ignore="ContentDescription"
tools:src="@mipmap/ic_launcher"/>
<LinearLayout
android:layout_width="wrap_content"
@ -74,7 +74,8 @@
<FrameLayout
android:id="@+id/controlOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:layout_alignBottom="@+id/presentationView">
<Button
android:id="@+id/skipPresentation"