improved launch presentations
This commit is contained in:
parent
812a44512c
commit
d2fccb6fc7
|
@ -143,8 +143,29 @@ public class LaunchPresentation {
|
||||||
@JsonField(name = "url")
|
@JsonField(name = "url")
|
||||||
String url;
|
String url;
|
||||||
|
|
||||||
|
@JsonField(name = "density")
|
||||||
|
float density;
|
||||||
|
|
||||||
|
@JsonField(name = "width")
|
||||||
|
int width;
|
||||||
|
|
||||||
|
@JsonField(name = "height")
|
||||||
|
int height;
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getDensity() {
|
||||||
|
return density;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import android.support.annotation.StyleRes
|
||||||
import android.support.v4.view.ViewCompat
|
import android.support.v4.view.ViewCompat
|
||||||
import android.support.v7.app.TwilightManagerAccessor
|
import android.support.v7.app.TwilightManagerAccessor
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.MeasureSpec
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.Priority
|
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.promotionsEnabledKey
|
||||||
import org.mariotaku.twidere.constant.themeColorKey
|
import org.mariotaku.twidere.constant.themeColorKey
|
||||||
import org.mariotaku.twidere.constant.themeKey
|
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.hasInvalidAccount
|
||||||
import org.mariotaku.twidere.extension.model.shouldShow
|
import org.mariotaku.twidere.extension.model.shouldShow
|
||||||
import org.mariotaku.twidere.model.presentation.LaunchPresentation
|
import org.mariotaku.twidere.model.presentation.LaunchPresentation
|
||||||
|
@ -138,10 +140,10 @@ open class MainActivity : ChameleonActivity(), IBaseActivity<MainActivity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(main) lambda@ { _, insets ->
|
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,
|
controlOverlay.setPadding(0, insets.systemWindowInsetTop, 0, 0)
|
||||||
insets.systemWindowInsetRight, 0)
|
|
||||||
return@lambda insets.consumeSystemWindowInsets()
|
return@lambda insets.consumeSystemWindowInsets()
|
||||||
}
|
}
|
||||||
ViewSupport.setOutlineProvider(skipPresentation, ViewOutlineProviderCompat.BACKGROUND)
|
ViewSupport.setOutlineProvider(skipPresentation, ViewOutlineProviderCompat.BACKGROUND)
|
||||||
|
@ -163,10 +165,9 @@ open class MainActivity : ChameleonActivity(), IBaseActivity<MainActivity> {
|
||||||
}
|
}
|
||||||
val presentation = jsonCache.getList(RefreshLaunchPresentationsTask.JSON_CACHE_KEY,
|
val presentation = jsonCache.getList(RefreshLaunchPresentationsTask.JSON_CACHE_KEY,
|
||||||
LaunchPresentation::class.java)?.firstOrNull {
|
LaunchPresentation::class.java)?.firstOrNull {
|
||||||
it.shouldShow()
|
it.shouldShow(this)
|
||||||
}
|
}
|
||||||
if (presentation != null) {
|
if (presentation != null && displayPresentation(presentation)) {
|
||||||
displayPresentation(presentation)
|
|
||||||
launchLater()
|
launchLater()
|
||||||
} else {
|
} else {
|
||||||
launchDirectly()
|
launchDirectly()
|
||||||
|
@ -225,12 +226,24 @@ open class MainActivity : ChameleonActivity(), IBaseActivity<MainActivity> {
|
||||||
isNightBackup = nightState
|
isNightBackup = nightState
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun displayPresentation(presentation: LaunchPresentation) {
|
private fun displayPresentation(presentation: LaunchPresentation): Boolean {
|
||||||
skipPresentation.visibility = View.VISIBLE
|
skipPresentation.visibility = View.VISIBLE
|
||||||
controlOverlay.tag = presentation
|
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)
|
.priority(Priority.HIGH)
|
||||||
.into(presentationView)
|
.into(presentationView)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun launchDirectly() {
|
private fun launchDirectly() {
|
||||||
|
|
|
@ -19,17 +19,16 @@
|
||||||
|
|
||||||
package org.mariotaku.twidere.extension.model
|
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 org.mariotaku.twidere.model.presentation.LaunchPresentation
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
fun LaunchPresentation.shouldShow(context: Context): Boolean {
|
||||||
* Created by mariotaku on 2017/8/20.
|
|
||||||
*/
|
|
||||||
|
|
||||||
fun LaunchPresentation.shouldShow(): Boolean {
|
|
||||||
// Check language
|
// Check language
|
||||||
val locale = Locale.getDefault()
|
val userLocales = context.resources.configuration.localesCompat
|
||||||
if (locales != null && locales.none { it.matches(locale) }) {
|
if (locales != null && locales.none { it.matchesAny(userLocales) }) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Check date/time
|
// Check date/time
|
||||||
|
@ -53,4 +52,34 @@ fun LaunchPresentation.Locale.matches(locale: Locale): Boolean {
|
||||||
return locale.country.isNullOrEmpty()
|
return locale.country.isNullOrEmpty()
|
||||||
}
|
}
|
||||||
return country == locale.country
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.mariotaku.twidere.task.filter
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.mariotaku.restfu.annotation.method.GET
|
import org.mariotaku.restfu.annotation.method.GET
|
||||||
import org.mariotaku.restfu.http.HttpRequest
|
import org.mariotaku.restfu.http.HttpRequest
|
||||||
|
import org.mariotaku.twidere.BuildConfig
|
||||||
import org.mariotaku.twidere.model.presentation.LaunchPresentation
|
import org.mariotaku.twidere.model.presentation.LaunchPresentation
|
||||||
import org.mariotaku.twidere.task.BaseAbstractTask
|
import org.mariotaku.twidere.task.BaseAbstractTask
|
||||||
import org.mariotaku.twidere.util.JsonSerializer
|
import org.mariotaku.twidere.util.JsonSerializer
|
||||||
|
@ -33,10 +34,14 @@ import java.io.IOException
|
||||||
*/
|
*/
|
||||||
class RefreshLaunchPresentationsTask(context: Context) : BaseAbstractTask<Unit?, Boolean, (Boolean) -> Unit>(context) {
|
class RefreshLaunchPresentationsTask(context: Context) : BaseAbstractTask<Unit?, Boolean, (Boolean) -> Unit>(context) {
|
||||||
override fun doLongOperation(params: Unit?): Boolean {
|
override fun doLongOperation(params: Unit?): Boolean {
|
||||||
val request = HttpRequest.Builder()
|
val builder = HttpRequest.Builder()
|
||||||
.method(GET.METHOD)
|
builder.method(GET.METHOD)
|
||||||
.url("https://twidere.mariotaku.org/assets/data/launch_presentations.json")
|
if (BuildConfig.DEBUG) {
|
||||||
.build()
|
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 {
|
try {
|
||||||
val presentations = restHttpClient.newCall(request).execute().use {
|
val presentations = restHttpClient.newCall(request).execute().use {
|
||||||
if (!it.isSuccessful) return@use null
|
if (!it.isSuccessful) return@use null
|
||||||
|
|
|
@ -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>
|
|
@ -47,8 +47,8 @@
|
||||||
android:id="@+id/appIcon"
|
android:id="@+id/appIcon"
|
||||||
android:layout_width="48dp"
|
android:layout_width="48dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
tools:src="@mipmap/ic_launcher"
|
tools:ignore="ContentDescription"
|
||||||
tools:ignore="ContentDescription"/>
|
tools:src="@mipmap/ic_launcher"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -74,7 +74,8 @@
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/controlOverlay"
|
android:id="@+id/controlOverlay"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignBottom="@+id/presentationView">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/skipPresentation"
|
android:id="@+id/skipPresentation"
|
||||||
|
|
Loading…
Reference in New Issue