implementing navbar transparent

added https support for fanfou
This commit is contained in:
Mariotaku Lee 2017-06-25 11:36:54 +08:00
parent c747a3bfad
commit 641341b5ee
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
57 changed files with 394 additions and 277 deletions

View File

@ -58,9 +58,10 @@ subprojects {
LoganSquare : '1.3.7',
IABv3 : '1.0.38',
Mime4J : '0.7.2',
Stetho : '1.4.2',
OkHttp : '3.8.1',
Stetho : '1.5.0',
OSMDroid : '5.6.4',
LeakCanary : '1.5',
LeakCanary : '1.5.1',
TwitterText : '1.14.3',
MediaViewerLibrary : '0.9.23',
MultiValueSwitch : '0.9.8',

View File

@ -282,6 +282,8 @@ public interface SharedPreferenceConstants {
String KEY_STREAMING_NON_METERED_NETWORK = "streaming_non_metered_network";
@ExportablePreference(BOOLEAN)
String KEY_STREAMING_POWER_SAVING = "streaming_power_saving";
@ExportablePreference(STRING)
String KEY_NAVBAR_STYLE = "navbar_style";
// Internal preferences

View File

@ -175,7 +175,7 @@ dependencies {
compile "com.github.mariotaku.RestFu:library:${libVersions['RestFu']}"
compile "com.github.mariotaku.RestFu:okhttp3:${libVersions['RestFu']}"
compile "com.github.mariotaku.RestFu:logansquare:${libVersions['RestFu']}"
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile "com.squareup.okhttp3:okhttp:${libVersions['OkHttp']}"
compile 'com.lnikkila:extendedtouchview:0.1.0'
compile 'com.google.dagger:dagger:2.8'
compile 'org.attoparser:attoparser:2.0.3.RELEASE'

View File

@ -32,11 +32,11 @@ class HttpClientFactoryTest {
val format1 = "https://proxy.com/[SCHEME]/[AUTHORITY]/[PATH][?QUERY][#FRAGMENT]"
val format2 = "https://proxy.com/[AUTHORITY]/[PATH][?QUERY][#FRAGMENT]"
val format3 = "https://proxy.com/[AUTHORITY][/PATH][?QUERY][#FRAGMENT]"
val url1 = HttpUrl.parse("https://example.com:8080/path?query=value#fragment")
val url2 = HttpUrl.parse("https://example.com:8080/path?query=value")
val url3 = HttpUrl.parse("https://example.com:8080/path#fragment")
val url4 = HttpUrl.parse("https://example.com:8080/path")
val url5 = HttpUrl.parse("https://example.com/path")
val url1 = HttpUrl.parse("https://example.com:8080/path?query=value#fragment")!!
val url2 = HttpUrl.parse("https://example.com:8080/path?query=value")!!
val url3 = HttpUrl.parse("https://example.com:8080/path#fragment")!!
val url4 = HttpUrl.parse("https://example.com:8080/path")!!
val url5 = HttpUrl.parse("https://example.com/path")!!
Assert.assertEquals("https://proxy.com/https/example.com%3A8080/path?query=value#fragment",
HttpClientFactory.replaceUrl(url1, format1))

View File

@ -27,7 +27,6 @@
android:enabled="false"
android:icon="@drawable/leak_canary_icon"
android:label="@string/leak_canary_display_activity_label"
android:taskAffinity="com.squareup.leakcanary"
android:theme="@style/leak_canary_LeakCanary.Base">
<intent-filter>
<action

View File

@ -87,6 +87,11 @@ public class DebugModeUtils {
static void initLeakCanary(Application application) {
if (!BuildConfig.LEAK_CANARY_ENABLED) return;
LeakCanary.enableDisplayLeakActivity(application);
if (LeakCanary.isInAnalyzerProcess(application)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
sRefWatcher = LeakCanary.install(application);
}

View File

@ -15,13 +15,13 @@
"name": "Fanfou",
"type": "fanfou",
"localized_name": "@string/provider_fanfou",
"api_url_format": "http://api.fanfou.com/",
"api_url_format": "https://api2.fanfou.com/",
"auth_type": "oauth",
"same_oauth_url": true,
"no_version_suffix": true,
"consumer_key": "86d1146dda1d21d59351008a1d1058fd",
"consumer_secret": "c00f4b83dbfc52e2ed78a21d4edfc3cc",
"sign_up_url": "http://fanfou.com/register"
"sign_up_url": "https://fanfou.com/register"
},
{
"name": "Quitter.se",

View File

@ -0,0 +1,35 @@
/*
* 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/>.
*/
package org.mariotaku.ktextension
import android.annotation.TargetApi
import android.graphics.Rect
import android.os.Build
import android.support.v4.view.WindowInsetsCompat
import android.view.WindowInsets
inline val WindowInsetsCompat.systemWindowInsets: Rect
get() = Rect(systemWindowInsetLeft, systemWindowInsetTop, systemWindowInsetRight,
systemWindowInsetBottom)
inline val WindowInsets.systemWindowInsets: Rect
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
get() = Rect(systemWindowInsetLeft, systemWindowInsetTop, systemWindowInsetRight,
systemWindowInsetBottom)

View File

@ -25,6 +25,7 @@ import android.content.*
import android.content.res.Resources
import android.graphics.Rect
import android.nfc.NfcAdapter
import android.os.Build
import android.os.Bundle
import android.support.annotation.StyleRes
import android.support.v4.graphics.ColorUtils
@ -38,6 +39,7 @@ import android.util.AttributeSet
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import com.squareup.otto.Bus
import nl.komponents.kovenant.Promise
import org.mariotaku.chameleon.Chameleon
@ -51,11 +53,8 @@ import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME
import org.mariotaku.twidere.activity.iface.IBaseActivity
import org.mariotaku.twidere.activity.iface.IControlBarActivity
import org.mariotaku.twidere.activity.iface.IThemedActivity
import org.mariotaku.twidere.constant.themeBackgroundAlphaKey
import org.mariotaku.twidere.constant.themeBackgroundOptionKey
import org.mariotaku.twidere.constant.themeColorKey
import org.mariotaku.twidere.constant.themeKey
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.constant.*
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowInsetsCallback
import org.mariotaku.twidere.model.DefaultFeatures
import org.mariotaku.twidere.preference.iface.IDialogPreference
import org.mariotaku.twidere.util.*
@ -66,17 +65,18 @@ import org.mariotaku.twidere.util.premium.ExtraFeaturesService
import org.mariotaku.twidere.util.schedule.StatusScheduleProvider
import org.mariotaku.twidere.util.support.ActivitySupport
import org.mariotaku.twidere.util.support.ActivitySupport.TaskDescriptionCompat
import org.mariotaku.twidere.util.support.WindowSupport
import org.mariotaku.twidere.util.sync.TimelineSyncManager
import org.mariotaku.twidere.util.theme.TwidereAppearanceCreator
import org.mariotaku.twidere.util.theme.getCurrentThemeResource
import org.mariotaku.twidere.view.iface.IExtendedView.OnFitSystemWindowsListener
import org.mariotaku.twidere.view.iface.IExtendedView.OnApplySystemWindowInsetsListener
import java.lang.reflect.InvocationTargetException
import java.util.*
import javax.inject.Inject
@SuppressLint("Registered")
open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThemedActivity,
IControlBarActivity, OnFitSystemWindowsListener, SystemWindowsInsetsCallback,
IControlBarActivity, OnApplySystemWindowInsetsListener, SystemWindowInsetsCallback,
KeyboardShortcutCallback, OnPreferenceDisplayDialogCallback {
@Inject
@ -169,13 +169,13 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
var keyMetaState: Int = 0
private set
override fun getSystemWindowsInsets(insets: Rect): Boolean {
override fun getSystemWindowInsets(insets: Rect): Boolean {
if (systemWindowsInsets == null) return false
insets.set(systemWindowsInsets)
return true
}
override fun onFitSystemWindows(insets: Rect) {
override fun onApplySystemWindowInsets(insets: Rect) {
if (systemWindowsInsets == null)
systemWindowsInsets = Rect(insets)
else {
@ -227,10 +227,12 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
StrictModeUtils.detectAllThreadPolicy()
}
val prefs = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
val themeResource = getThemeResource(prefs, prefs[themeKey], prefs[themeColorKey])
val themeColor = prefs[themeColorKey]
val themeResource = getThemeResource(prefs, prefs[themeKey], themeColor)
if (themeResource != 0) {
setTheme(themeResource)
}
setNavigationStyle(prefs[navbarStyleKey], themeColor)
super.onCreate(savedInstanceState)
ActivitySupport.setTaskDescription(this, TaskDescriptionCompat(title.toString(), null,
ColorUtils.setAlphaComponent(overrideTheme.colorToolbar, 0xFF)))
@ -371,6 +373,18 @@ open class BaseActivity : ChameleonActivity(), IBaseActivity<BaseActivity>, IThe
return getCurrentThemeResource(this, theme)
}
private fun setNavigationStyle(navbarStyle: String, themeColor: Int) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return
when (navbarStyle) {
"transparent" -> {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
}
"colored" -> {
WindowSupport.setNavigationBarColor(window, themeColor)
}
}
}
private fun findClass(name: String): Class<*>? {
var cls: Class<*>? = null
try {

View File

@ -211,7 +211,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
val refreshOnStart = preferences.getBoolean(SharedPreferenceConstants.KEY_REFRESH_ON_START, false)
var tabDisplayOptionInt = Utils.getTabDisplayOptionInt(this)
homeContent.onFitSystemWindowsListener = this
homeContent.onApplySystemWindowInsetsListener = this
mainPager.adapter = pagerAdapter
mainTabs.setViewPager(mainPager)
mainTabs.setOnPageChangeListener(this)
@ -376,11 +376,11 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
return true
}
override fun onFitSystemWindows(insets: Rect) {
super.onFitSystemWindows(insets)
override fun onApplySystemWindowInsets(insets: Rect) {
super.onApplySystemWindowInsets(insets)
val fragment = leftDrawerFragment
if (fragment is AccountsDashboardFragment) {
fragment.requestFitSystemWindows()
fragment.requestApplyInsets()
}
}
@ -391,7 +391,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
}
}
override fun getSystemWindowsInsets(insets: Rect): Boolean {
override fun getSystemWindowInsets(insets: Rect): Boolean {
if (mainTabs == null || homeContent == null) return false
val height = mainTabs.height
if (height != 0) {

View File

@ -54,7 +54,7 @@ import org.mariotaku.twidere.fragment.filter.FiltersImportBlocksFragment
import org.mariotaku.twidere.fragment.filter.FiltersImportMutesFragment
import org.mariotaku.twidere.fragment.filter.FiltersSubscriptionsFragment
import org.mariotaku.twidere.fragment.iface.IBaseFragment
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowInsetsCallback
import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment
import org.mariotaku.twidere.fragment.iface.IToolBarSupportFragment
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
@ -74,7 +74,7 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallb
import org.mariotaku.twidere.util.linkhandler.TwidereLinkMatcher
import org.mariotaku.twidere.util.theme.getCurrentThemeResource
class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IControlBarActivity,
class LinkHandlerActivity : BaseActivity(), SystemWindowInsetsCallback, IControlBarActivity,
SupportFragmentCallback {
private lateinit var multiSelectHandler: MultiSelectEventHandler
@ -205,11 +205,11 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
return false
}
override fun onFitSystemWindows(insets: Rect) {
super.onFitSystemWindows(insets)
override fun onApplySystemWindowInsets(insets: Rect) {
super.onApplySystemWindowInsets(insets)
val fragment = currentVisibleFragment
if (fragment is IBaseFragment<*>) {
fragment.requestFitSystemWindows()
fragment.requestApplyInsets()
}
}

View File

@ -35,10 +35,7 @@ import android.support.v4.view.ViewPager
import android.support.v4.widget.ViewDragHelper
import android.support.v7.app.WindowDecorActionBar
import android.support.v7.app.decorToolbar
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import android.view.*
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_media_viewer.*
import org.mariotaku.chameleon.Chameleon
@ -159,7 +156,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
override fun onApplyWindowInsets(left: Int, top: Int, right: Int, bottom: Int) {
val statusBarHeight = top - ThemeUtils.getActionBarHeight(this@MediaViewerActivity)
activityLayout.setStatusBarHeight(statusBarHeight)
onFitSystemWindows(Rect(left, top, right, bottom))
onApplySystemWindowInsets(Rect(left, top, right, bottom))
}
}
}
@ -270,6 +267,11 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
currentFragment
return super.onKeyUp(keyCode, event)
}
override fun toggleBar() {
setBarVisibility(!isBarShowing)
}
@ -405,13 +407,13 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
controlBarShowHideHelper.setControlBarVisibleAnimate(visible, listener)
}
override fun onFitSystemWindows(insets: Rect) {
super.onFitSystemWindows(insets)
override fun onApplySystemWindowInsets(insets: Rect) {
super.onApplySystemWindowInsets(insets)
val adapter = viewPager.adapter
if (adapter.count == 0) return
val fragment = adapter.instantiateItem(viewPager, viewPager.currentItem)
if (fragment is IBaseFragment<*>) {
fragment.requestFitSystemWindows()
fragment.requestApplyInsets()
}
}
@ -559,5 +561,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos
const val FLAG_SYSTEM_UI_HIDE_BARS = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_FULLSCREEN
}
interface Media
}

View File

@ -72,13 +72,13 @@ import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.EditTextEnterHandler.EnterListener
import org.mariotaku.twidere.util.content.ContentResolverUtils
import org.mariotaku.twidere.view.ProfileImageView
import org.mariotaku.twidere.view.iface.IExtendedView.OnFitSystemWindowsListener
import org.mariotaku.twidere.view.iface.IExtendedView.OnApplySystemWindowInsetsListener
/**
* Created by mariotaku on 15/1/6.
*/
class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<Cursor?>,
OnItemSelectedListener, OnItemClickListener, OnFitSystemWindowsListener,
OnItemSelectedListener, OnItemClickListener, OnApplySystemWindowInsetsListener,
SwipeDismissListViewTouchListener.DismissCallbacks {
private val systemWindowsInsets = Rect()
@ -113,7 +113,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
accountSpinner.setSelection(index)
}
}
mainContent.onFitSystemWindowsListener = this
mainContent.onApplySystemWindowInsetsListener = this
suggestionsList.adapter = SuggestionsAdapter(this)
suggestionsList.onItemClickListener = this
@ -259,7 +259,7 @@ class QuickSearchBarActivity : BaseActivity(), OnClickListener, LoaderCallbacks<
adapter.changeCursor(null)
}
override fun onFitSystemWindows(insets: Rect) {
override fun onApplySystemWindowInsets(insets: Rect) {
systemWindowsInsets.set(insets)
updateWindowAttributes()
}

View File

@ -28,6 +28,7 @@ import android.os.Bundle
import android.support.annotation.DrawableRes
import android.support.annotation.XmlRes
import android.support.v4.app.Fragment
import android.support.v4.view.ViewCompat
import android.support.v7.app.AlertDialog
import android.support.v7.preference.Preference
import android.support.v7.preference.PreferenceFragmentCompat
@ -42,6 +43,7 @@ import kotlinx.android.synthetic.main.activity_settings.*
import org.mariotaku.chameleon.Chameleon
import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.set
import org.mariotaku.ktextension.systemWindowInsets
import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.ACTION_NAVIGATION_BACK
@ -87,6 +89,12 @@ class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartF
slidingPane.setShadowResourceRight(R.drawable.sliding_pane_shadow_right)
slidingPane.sliderFadeColor = 0
ViewCompat.setOnApplyWindowInsetsListener(slidingPane) listener@ { _, insets ->
onApplySystemWindowInsets(insets.systemWindowInsets)
entriesList.setPadding(0, insets.systemWindowInsetTop, 0, insets.systemWindowInsetBottom)
return@listener insets
}
initEntries()
entriesList.adapter = entriesAdapter
entriesList.choiceMode = AbsListView.CHOICE_MODE_SINGLE

View File

@ -1249,7 +1249,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher,
private val CustomAPIConfig.signUpUrlOrDefault: String?
get() = signUpUrl ?: when (type) {
AccountType.TWITTER -> "https://twitter.com/signup"
AccountType.FANFOU -> "http://fanfou.com/register"
AccountType.FANFOU -> "https://fanfou.com/register"
else -> null
}

View File

@ -82,6 +82,8 @@ val homeRefreshMentionsKey = KBooleanKey(KEY_HOME_REFRESH_MENTIONS, true)
val homeRefreshDirectMessagesKey = KBooleanKey(KEY_HOME_REFRESH_DIRECT_MESSAGES, true)
val homeRefreshSavedSearchesKey = KBooleanKey(KEY_HOME_REFRESH_SAVED_SEARCHES, true)
val composeStatusVisibilityKey = KNullableStringKey("compose_status_visibility", null)
val navbarStyleKey = KStringKey(KEY_NAVBAR_STYLE, "default")
object cacheSizeLimitKey : KSimpleKey<Int>(KEY_CACHE_SIZE_LIMIT, 300) {
override fun read(preferences: SharedPreferences) = preferences.getInt(key, def).coerceIn(100,
500)

View File

@ -96,7 +96,7 @@ abstract class AbsContentListViewFragment<A : ListAdapter> : BaseFragment(),
setRefreshEnabled(false)
}
override fun onAttach(context: Context?) {
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is IControlBarActivity) {
context.registerControlBarOffsetListener(this)
@ -149,7 +149,7 @@ abstract class AbsContentListViewFragment<A : ListAdapter> : BaseFragment(),
super.onStop()
}
override fun fitSystemWindows(insets: Rect) {
override fun applySystemWindowInsets(insets: Rect) {
listView.setPadding(insets.left, insets.top, insets.right, insets.bottom)
errorContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom)
progressContainer.setPadding(insets.left, insets.top, insets.right, insets.bottom)

View File

@ -162,7 +162,7 @@ abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<Recycle
refreshEnabled = position == ILoadMoreSupportAdapter.NONE
}
override fun onAttach(context: Context?) {
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is IControlBarActivity) {
context.registerControlBarOffsetListener(this)
@ -249,7 +249,7 @@ abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<Recycle
protected open val extraContentPadding: Rect
get() = Rect()
override fun fitSystemWindows(insets: Rect) {
override fun applySystemWindowInsets(insets: Rect) {
val extraPadding = extraContentPadding
recyclerView.setPadding(insets.left + extraPadding.left, insets.top + extraPadding.top,
insets.right + extraPadding.right, insets.bottom + extraPadding.bottom)

View File

@ -35,7 +35,7 @@ import org.mariotaku.twidere.view.iface.IExtendedView
* Created by mariotaku on 16/3/16.
*/
abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInterface,
SupportFragmentCallback, IBaseFragment.SystemWindowsInsetsCallback, ControlBarOffsetListener,
SupportFragmentCallback, IBaseFragment.SystemWindowInsetsCallback, ControlBarOffsetListener,
HideUiOnScroll, OnPageChangeListener, IToolBarSupportFragment, KeyboardShortcutCallback {
protected lateinit var pagerAdapter: SupportTabsAdapter
@ -64,7 +64,7 @@ abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInte
if (i > currentItem - pageLimit - 1 || i < currentItem + pageLimit) {
val obj = pagerAdapter.instantiateItem(viewPager, i)
if (obj is IBaseFragment<*>) {
obj.requestFitSystemWindows()
obj.requestApplyInsets()
}
}
}
@ -87,7 +87,7 @@ abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInte
protected abstract fun addTabs(adapter: SupportTabsAdapter)
override fun onAttach(context: Context?) {
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is IControlBarActivity) {
context.registerControlBarOffsetListener(this)
@ -134,10 +134,10 @@ abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInte
return false
}
override fun fitSystemWindows(insets: Rect) {
override fun applySystemWindowInsets(insets: Rect) {
}
override fun getSystemWindowsInsets(insets: Rect): Boolean {
override fun getSystemWindowInsets(insets: Rect): Boolean {
if (toolbarTabs == null) return false
insets.set(0, toolbarContainer.height, 0, 0)
return true

View File

@ -277,7 +277,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks<AccountsInfo>,
}
}
override fun fitSystemWindows(insets: Rect) {
override fun applySystemWindowInsets(insets: Rect) {
systemWindowsInsets.set(insets)
updateSystemWindowsInsets()
}

View File

@ -97,12 +97,12 @@ open class BaseFragment : Fragment(), IBaseFragment<BaseFragment> {
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
requestFitSystemWindows()
requestApplyInsets()
}
override fun onAttach(context: Context?) {
override fun onAttach(context: Context) {
super.onAttach(context)
GeneralComponent.get(context!!).inject(this)
GeneralComponent.get(context).inject(this)
}
override fun executeAfterFragmentResumed(useHandler: Boolean, action: (BaseFragment) -> Unit)

View File

@ -75,7 +75,7 @@ abstract class BasePreferenceFragment : PreferenceFragmentCompat(), IBaseFragmen
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
requestFitSystemWindows()
requestApplyInsets()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -125,7 +125,7 @@ abstract class BasePreferenceFragment : PreferenceFragmentCompat(), IBaseFragmen
return actionHelper.executeAfterFragmentResumed(useHandler, action)
}
override fun fitSystemWindows(insets: Rect) {
override fun applySystemWindowInsets(insets: Rect) {
listView.setPadding(insets.left, insets.top, insets.right, insets.bottom)
}

View File

@ -22,7 +22,9 @@ package org.mariotaku.twidere.fragment
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.os.Bundle
import android.support.v4.view.ViewCompat
import android.support.v7.preference.PreferenceScreen
import android.view.View
import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.activity.SettingsActivity
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_SHOULD_TERMINATE
@ -57,6 +59,12 @@ class SettingsDetailsFragment : BasePreferenceFragment(), OnSharedPreferenceChan
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
listView.fitsSystemWindows = true
ViewCompat.requestApplyInsets(listView)
}
override fun onStart() {
super.onStart()
preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)

View File

@ -695,7 +695,6 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
}
override fun onException(callback: Any?, exception: MicroBlogException) {
val context = this.context ?: return
Toast.makeText(context, exception.getErrorMessage(context), Toast.LENGTH_SHORT).show()
}
}

View File

@ -112,7 +112,7 @@ import org.mariotaku.twidere.extension.model.*
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
import org.mariotaku.twidere.fragment.AbsStatusesFragment.StatusesFragmentDelegate
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowInsetsCallback
import org.mariotaku.twidere.fragment.iface.IToolBarSupportFragment
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
@ -152,7 +152,7 @@ import java.util.*
class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
OnSizeChangedListener, OnTouchListener, DrawerCallback, SupportFragmentCallback,
SystemWindowsInsetsCallback, RefreshScrollTopInterface, OnPageChangeListener,
SystemWindowInsetsCallback, RefreshScrollTopInterface, OnPageChangeListener,
KeyboardShortcutCallback, UserColorChangedListener, UserNicknameChangedListener,
IToolBarSupportFragment, StatusesFragmentDelegate,
AbsContentRecyclerViewFragment.RefreshCompleteListener {
@ -554,7 +554,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
return false
}
override fun getSystemWindowsInsets(insets: Rect): Boolean {
override fun getSystemWindowInsets(insets: Rect): Boolean {
return false
}
@ -1158,7 +1158,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
private val keyboardShortcutRecipient: Fragment?
get() = currentVisibleFragment
override fun fitSystemWindows(insets: Rect) {
override fun applySystemWindowInsets(insets: Rect) {
}
override fun setupWindow(activity: FragmentActivity): Boolean {
@ -1295,7 +1295,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
override fun onSizeChanged(view: View, w: Int, h: Int, oldw: Int, oldh: Int) {
bannerWidth = w
if (w != oldw || h != oldh) {
requestFitSystemWindows()
requestApplyInsets()
}
}

View File

@ -54,7 +54,7 @@ import org.mariotaku.twidere.constant.newDocumentApiKey
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
import org.mariotaku.twidere.extension.onShow
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowInsetsCallback
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
import org.mariotaku.twidere.fragment.statuses.UserListTimelineFragment
import org.mariotaku.twidere.fragment.users.UserListMembersFragment
@ -68,7 +68,7 @@ import org.mariotaku.twidere.model.event.UserListUpdatedEvent
import org.mariotaku.twidere.util.*
class UserListFragment : AbsToolbarTabPagesFragment(), OnClickListener,
LoaderCallbacks<SingleResponse<ParcelableUserList>>, SystemWindowsInsetsCallback,
LoaderCallbacks<SingleResponse<ParcelableUserList>>, SystemWindowInsetsCallback,
SupportFragmentCallback {
private var userListLoaderInitialized: Boolean = false

View File

@ -39,31 +39,31 @@ interface IBaseFragment<out F : Fragment> {
val tabId: Long
get() = (this as Fragment).arguments?.getLong(IntentConstants.EXTRA_TAB_ID, -1L) ?: -1L
fun requestFitSystemWindows() {
fun requestApplyInsets() {
val fragment = this as Fragment
val activity = fragment.activity
val parentFragment = fragment.parentFragment
val callback: IBaseFragment.SystemWindowsInsetsCallback
if (parentFragment is IBaseFragment.SystemWindowsInsetsCallback) {
val callback: SystemWindowInsetsCallback
if (parentFragment is SystemWindowInsetsCallback) {
callback = parentFragment
} else if (activity is IBaseFragment.SystemWindowsInsetsCallback) {
} else if (activity is SystemWindowInsetsCallback) {
callback = activity
} else {
return
}
val insets = Rect()
if (callback.getSystemWindowsInsets(insets)) {
fitSystemWindows(insets)
if (callback.getSystemWindowInsets(insets)) {
applySystemWindowInsets(insets)
}
}
fun fitSystemWindows(insets: Rect) {
val fragment = this as Fragment
fragment.view?.setPadding(insets.left, insets.top, insets.right, insets.bottom)
fun applySystemWindowInsets(insets: Rect) {
this as Fragment
view?.setPadding(insets.left, insets.top, insets.right, insets.bottom)
}
interface SystemWindowsInsetsCallback {
fun getSystemWindowsInsets(insets: Rect): Boolean
interface SystemWindowInsetsCallback {
fun getSystemWindowInsets(insets: Rect): Boolean
}
fun executeAfterFragmentResumed(useHandler: Boolean = false, action: (F) -> Unit): Promise<Unit, Exception>

View File

@ -253,7 +253,7 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
return inflater.inflate(R.layout.layout_media_viewer_exo_player_view, parent, false)
}
override fun fitSystemWindows(insets: Rect) {
override fun applySystemWindowInsets(insets: Rect) {
val lp = videoControl.layoutParams
if (lp is ViewGroup.MarginLayoutParams) {
lp.bottomMargin = insets.bottom
@ -271,7 +271,7 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
requestFitSystemWindows()
requestApplyInsets()
}
override fun executeAfterFragmentResumed(useHandler: Boolean, action: (ExoPlayerPageFragment) -> Unit) = TODO()
@ -384,7 +384,7 @@ class ExoPlayerPageFragment : MediaViewerFragment(), IBaseFragment<ExoPlayerPage
override val specialCharacter: Char = '_'
override fun inputStream(): InputStream {
return request().body().byteStream()
return request().body()!!.byteStream()
}
override fun close() {

View File

@ -76,7 +76,7 @@ class ExternalBrowserPageFragment : MediaViewerFragment() {
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser) {
activity?.supportInvalidateOptionsMenu()
activity?.invalidateOptionsMenu()
}
}
}

View File

@ -61,9 +61,8 @@ class ImagePageFragment : SubsampleImageViewerFragment() {
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
val activity = activity
if (isVisibleToUser && activity != null) {
activity.supportInvalidateOptionsMenu()
if (isVisibleToUser) {
activity?.invalidateOptionsMenu()
}
}
@ -85,9 +84,8 @@ class ImagePageFragment : SubsampleImageViewerFragment() {
override fun onMediaLoadStateChange(@State state: Int) {
mediaLoadState = state
val activity = activity
if (userVisibleHint && activity != null) {
activity.supportInvalidateOptionsMenu()
if (userVisibleHint) {
activity?.invalidateOptionsMenu()
}
}

View File

@ -168,7 +168,7 @@ class VideoPageFragment : CacheDownloadMediaViewerFragment(), IBaseFragment<Vide
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
requestFitSystemWindows()
requestApplyInsets()
}
override fun getDownloadExtra(): Any? {
@ -197,7 +197,7 @@ class VideoPageFragment : CacheDownloadMediaViewerFragment(), IBaseFragment<Vide
videoView.setVideoURI(result.cacheUri)
videoControl.visibility = View.GONE
setMediaViewVisible(true)
activity.supportInvalidateOptionsMenu()
activity.invalidateOptionsMenu()
}
override fun releaseMediaResources() {
@ -261,7 +261,7 @@ class VideoPageFragment : CacheDownloadMediaViewerFragment(), IBaseFragment<Vide
super.setUserVisibleHint(isVisibleToUser)
if (activity == null) return
if (isVisibleToUser) {
activity.supportInvalidateOptionsMenu()
activity?.invalidateOptionsMenu()
} else if (videoView.isPlaying) {
videoView.pause()
updatePlayerState()
@ -295,7 +295,7 @@ class VideoPageFragment : CacheDownloadMediaViewerFragment(), IBaseFragment<Vide
return inflater.inflate(R.layout.layout_media_viewer_texture_video_view, container, false)
}
override fun fitSystemWindows(insets: Rect) {
override fun applySystemWindowInsets(insets: Rect) {
val lp = videoControl.layoutParams
if (lp is ViewGroup.MarginLayoutParams) {
lp.bottomMargin = insets.bottom

View File

@ -286,7 +286,7 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment,
adapter.conversation = data
activity?.supportInvalidateOptionsMenu()
activity?.invalidateOptionsMenu()
}
private fun performDestroyConversation() {

View File

@ -288,7 +288,7 @@ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks<List<Parc
usersAdapter.setCheckState(user.key, true)
}
usersAdapter.notifyDataSetChanged()
activity?.supportInvalidateOptionsMenu()
activity?.invalidateOptionsMenu()
}

View File

@ -131,7 +131,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
}
adapter.listener = object : MessagesConversationAdapter.Listener {
override fun onMediaClick(position: Int, media: ParcelableMedia, accountKey: UserKey?) {
val message = adapter.getMessage(position) ?: return
val message = adapter.getMessage(position)
IntentUtils.openMediaDirectly(context = context, accountKey = accountKey,
media = message.media, current = media,
newDocument = preferences[newDocumentApiKey], message = message)
@ -314,7 +314,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
override fun onLoadMoreContents(position: Long) {
if (ILoadMoreSupportAdapter.START !in position) return
val message = adapter.getMessage(adapter.messageRange.endInclusive) ?: return
val message = adapter.getMessage(adapter.messageRange.endInclusive)
setLoadMoreIndicatorPosition(position)
val param = GetMessagesTask.LoadMoreMessageTaskParam(context, accountKey, conversationId,
message.id)
@ -326,7 +326,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
if (menuInfo !is ExtendedRecyclerView.ContextMenuInfo) return
when (menuInfo.recyclerViewId) {
R.id.recyclerView -> {
val message = adapter.getMessage(menuInfo.position) ?: return
val message = adapter.getMessage(menuInfo.position)
val conversation = adapter.conversation
menu.setHeaderTitle(message.getSummaryText(context, userColorNameManager, conversation,
preferences[nameFirstKey]))
@ -345,7 +345,7 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
}
when (menuInfo.recyclerViewId) {
R.id.recyclerView -> {
val message = adapter.getMessage(menuInfo.position) ?: return true
val message = adapter.getMessage(menuInfo.position)
when (item.itemId) {
R.id.copy -> {
ClipboardUtils.setText(context, message.text_unescaped)

View File

@ -43,7 +43,7 @@ import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.extension.model.getAccountType
import org.mariotaku.twidere.fragment.AbsToolbarTabPagesFragment
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowInsetsCallback
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
import org.mariotaku.twidere.fragment.statuses.MediaStatusesSearchFragment
@ -59,7 +59,7 @@ import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.ThemeUtils
class SearchFragment : AbsToolbarTabPagesFragment(), RefreshScrollTopInterface,
SupportFragmentCallback, SystemWindowsInsetsCallback, ControlBarOffsetListener,
SupportFragmentCallback, SystemWindowInsetsCallback, ControlBarOffsetListener,
OnPageChangeListener, LinkHandlerActivity.HideUiOnScroll {
val accountKey: UserKey

View File

@ -38,6 +38,8 @@ class SearchUsersFragment : ParcelableUsersFragment() {
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
val query = args.getString(EXTRA_QUERY)
val pagination = args.getParcelable<Pagination?>(EXTRA_PAGINATION)
return UserSearchLoader(context, accountKey, query, adapter.getData(), fromUser)
return UserSearchLoader(context, accountKey, query, adapter.getData(), fromUser).apply {
this.pagination = pagination
}
}
}

View File

@ -197,7 +197,7 @@ class UserTimelineLoader(
if (atomLink != null || elementName != "link" || attributes == null) return
if (attributes["rel"] == "alternate" && attributes["type"] == "application/atom+xml") {
val href = attributes["href"] ?: return
atomLink = HttpUrl.parse(profileUrl).resolve(href).toString()
atomLink = HttpUrl.parse(profileUrl)?.resolve(href)?.toString()
}
}
}

View File

@ -159,7 +159,7 @@ class CacheProvider : ContentProvider() {
throw IllegalArgumentException(uri.toString())
if (AUTHORITY_TWIDERE_CACHE != uri.authority)
throw IllegalArgumentException(uri.toString())
return ByteString.decodeBase64(uri.lastPathSegment).utf8()
return ByteString.decodeBase64(uri.lastPathSegment)!!.utf8()
}

View File

@ -41,7 +41,6 @@ import org.mariotaku.twidere.TwidereConstants.OAUTH_CALLBACK_OOB
import org.mariotaku.twidere.util.net.SimpleCookieJar
import java.io.IOException
import java.io.Reader
import java.net.URI
class OAuthPasswordAuthenticator(
private val oauth: TwitterOAuth,
@ -406,8 +405,8 @@ class OAuthPasswordAuthenticator(
val location = response.header("Location")
val builder = response.newBuilder()
if (!TextUtils.isEmpty(location) && !endpoint.checkEndpoint(location)) {
val originalLocation = HttpUrl.get(URI.create("https://api.twitter.com/").resolve(location))
val locationBuilder = HttpUrl.parse(endpoint.url).newBuilder()
val originalLocation = HttpUrl.parse("https://api.twitter.com/")?.resolve(location)!!
val locationBuilder = HttpUrl.parse(endpoint.url)!!.newBuilder()
for (pathSegments in originalLocation.pathSegments()) {
locationBuilder.addPathSegment(pathSegments)
}

View File

@ -135,7 +135,7 @@ open class OnLinkClickHandler(
if (manager != null && manager.isActive) return
val uri = Uri.parse(link)
if (uri.isRelative && accountKey != null && accountKey.host != null) {
val absUri = HttpUrl.parse("http://${accountKey.host}/").resolve(link).toUri()
val absUri = HttpUrl.parse("http://${accountKey.host}/")?.resolve(link)?.toUri()!!
openLink(context, preferences, absUri)
return
}

View File

@ -45,7 +45,7 @@ class TwidereRestRequestFactory(
val bodyType = restMethod.bodyType
val extras = restMethod.extras
if (queries != null && extraRequestParams != null) {
if (extraRequestParams != null) {
for ((key, value) in extraRequestParams) {
queries.add(key, value)
}

View File

@ -20,10 +20,10 @@
package org.mariotaku.twidere.view
import android.content.Context
import android.os.Build
import android.support.v13.view.inputmethod.EditorInfoCompat
import android.support.v13.view.inputmethod.InputConnectionCompat
import android.support.v13.view.inputmethod.InputContentInfoCompat
import android.support.v4.os.BuildCompat
import android.text.InputType
import android.text.Selection
import android.text.method.ArrowKeyMovementMethod
@ -57,7 +57,7 @@ class ComposeEditText(
init {
setupEmojiFactory()
setTokenizer(StatusTextTokenizer())
onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
onItemClickListener = AdapterView.OnItemClickListener { _, _, _, _ ->
removeIMESuggestions()
}
// HACK: remove AUTO_COMPLETE flag to force IME show auto completion
@ -99,7 +99,8 @@ class ComposeEditText(
val callback = InputConnectionCompat.OnCommitContentListener { inputContentInfo, flags, _ ->
// read and display inputContentInfo asynchronously
if (BuildCompat.isAtLeastNMR1() && InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION in flags) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1
&& InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION in flags) {
try {
inputContentInfo.requestPermission()
} catch (e: Exception) {

View File

@ -19,11 +19,14 @@
package org.mariotaku.twidere.view
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.WindowInsets
import android.widget.FrameLayout
import org.mariotaku.ktextension.systemWindowInsets
import org.mariotaku.twidere.view.iface.IExtendedView
open class ExtendedFrameLayout(context: Context, attrs: AttributeSet? = null) :
@ -31,7 +34,7 @@ open class ExtendedFrameLayout(context: Context, attrs: AttributeSet? = null) :
override var touchInterceptor: IExtendedView.TouchInterceptor? = null
override var onSizeChangedListener: IExtendedView.OnSizeChangedListener? = null
override var onFitSystemWindowsListener: IExtendedView.OnFitSystemWindowsListener? = null
override var onApplySystemWindowInsetsListener: IExtendedView.OnApplySystemWindowInsetsListener? = null
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (touchInterceptor != null) {
@ -49,11 +52,10 @@ open class ExtendedFrameLayout(context: Context, attrs: AttributeSet? = null) :
return super.onInterceptTouchEvent(event)
}
override fun fitSystemWindows(insets: Rect): Boolean {
if (onFitSystemWindowsListener != null) {
onFitSystemWindowsListener!!.onFitSystemWindows(insets)
}
return super.fitSystemWindows(insets)
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
onApplySystemWindowInsetsListener?.onApplySystemWindowInsets(insets.systemWindowInsets)
return super.onApplyWindowInsets(insets)
}
override fun onTouchEvent(event: MotionEvent): Boolean {

View File

@ -19,11 +19,14 @@
package org.mariotaku.twidere.view
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.support.v7.widget.AppCompatImageView
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.WindowInsets
import org.mariotaku.ktextension.systemWindowInsets
import org.mariotaku.twidere.view.iface.IExtendedView
class ExtendedImageView(context: Context, attrs: AttributeSet? = null) :
@ -31,16 +34,9 @@ class ExtendedImageView(context: Context, attrs: AttributeSet? = null) :
override var onSizeChangedListener: IExtendedView.OnSizeChangedListener? = null
override var touchInterceptor: IExtendedView.TouchInterceptor? = null
override var onFitSystemWindowsListener: IExtendedView.OnFitSystemWindowsListener? = null
override var onApplySystemWindowInsetsListener: IExtendedView.OnApplySystemWindowInsetsListener? = null
override fun fitSystemWindows(insets: Rect): Boolean {
if (onFitSystemWindowsListener != null) {
onFitSystemWindowsListener!!.onFitSystemWindows(insets)
}
return super.fitSystemWindows(insets)
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (touchInterceptor != null) {
val ret = touchInterceptor!!.dispatchTouchEvent(this, event)
@ -64,4 +60,10 @@ class ExtendedImageView(context: Context, attrs: AttributeSet? = null) :
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
onApplySystemWindowInsetsListener?.onApplySystemWindowInsets(insets.systemWindowInsets)
return super.onApplyWindowInsets(insets)
}
}

View File

@ -19,18 +19,21 @@
package org.mariotaku.twidere.view
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.WindowInsets
import android.widget.LinearLayout
import org.mariotaku.ktextension.systemWindowInsets
import org.mariotaku.twidere.view.iface.IExtendedView
class ExtendedLinearLayout(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs), IExtendedView {
override var touchInterceptor: IExtendedView.TouchInterceptor? = null
override var onSizeChangedListener: IExtendedView.OnSizeChangedListener? = null
override var onFitSystemWindowsListener: IExtendedView.OnFitSystemWindowsListener? = null
override var onApplySystemWindowInsetsListener: IExtendedView.OnApplySystemWindowInsetsListener? = null
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (touchInterceptor != null) {
@ -48,11 +51,10 @@ class ExtendedLinearLayout(context: Context, attrs: AttributeSet? = null) : Line
return super.onInterceptTouchEvent(event)
}
override fun fitSystemWindows(insets: Rect): Boolean {
if (onFitSystemWindowsListener != null) {
onFitSystemWindowsListener!!.onFitSystemWindows(insets)
}
return super.fitSystemWindows(insets)
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
onApplySystemWindowInsetsListener?.onApplySystemWindowInsets(insets.systemWindowInsets)
return super.onApplyWindowInsets(insets)
}
override fun onTouchEvent(event: MotionEvent): Boolean {

View File

@ -19,6 +19,7 @@
package org.mariotaku.twidere.view
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Rect
import android.graphics.drawable.Drawable
@ -26,7 +27,9 @@ import android.os.Build
import android.support.annotation.DrawableRes
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.WindowInsets
import android.widget.RelativeLayout
import org.mariotaku.ktextension.systemWindowInsets
import org.mariotaku.twidere.R
import org.mariotaku.twidere.view.iface.IExtendedView
@ -35,7 +38,7 @@ open class ExtendedRelativeLayout(context: Context, attrs: AttributeSet? = null)
override var touchInterceptor: IExtendedView.TouchInterceptor? = null
override var onSizeChangedListener: IExtendedView.OnSizeChangedListener? = null
override var onFitSystemWindowsListener: IExtendedView.OnFitSystemWindowsListener? = null
override var onApplySystemWindowInsetsListener: IExtendedView.OnApplySystemWindowInsetsListener? = null
private var usePaddingBackup: Boolean = false
private val paddingBackup = Rect()
@ -66,12 +69,6 @@ open class ExtendedRelativeLayout(context: Context, attrs: AttributeSet? = null)
return super.onInterceptTouchEvent(event)
}
@Deprecated("Deprecated in Android")
override fun fitSystemWindows(insets: Rect): Boolean {
onFitSystemWindowsListener?.onFitSystemWindows(insets)
@Suppress("DEPRECATION")
return super.fitSystemWindows(insets)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
if (touchInterceptor != null) {
@ -108,6 +105,12 @@ open class ExtendedRelativeLayout(context: Context, attrs: AttributeSet? = null)
restorePadding()
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
onApplySystemWindowInsetsListener?.onApplySystemWindowInsets(insets.systemWindowInsets)
return super.onApplyWindowInsets(insets)
}
private fun backupPadding() {
if (!usePaddingBackup) return
paddingBackup.set(paddingLeft, paddingTop, paddingRight, paddingBottom)

View File

@ -19,12 +19,14 @@
package org.mariotaku.twidere.view
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.WindowInsets
import org.mariotaku.chameleon.view.ChameleonSwipeRefreshLayout
import org.mariotaku.ktextension.systemWindowInsets
import org.mariotaku.twidere.view.iface.IExtendedView
/**
@ -35,7 +37,7 @@ class ExtendedSwipeRefreshLayout(context: Context, attrs: AttributeSet? = null)
override var touchInterceptor: IExtendedView.TouchInterceptor? = null
override var onSizeChangedListener: IExtendedView.OnSizeChangedListener? = null
override var onFitSystemWindowsListener: IExtendedView.OnFitSystemWindowsListener? = null
override var onApplySystemWindowInsetsListener: IExtendedView.OnApplySystemWindowInsetsListener? = null
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (touchInterceptor != null) {
@ -53,13 +55,6 @@ class ExtendedSwipeRefreshLayout(context: Context, attrs: AttributeSet? = null)
return super.onInterceptTouchEvent(event)
}
override fun fitSystemWindows(insets: Rect): Boolean {
if (onFitSystemWindowsListener != null) {
onFitSystemWindowsListener!!.onFitSystemWindows(insets)
}
return super.fitSystemWindows(insets)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
if (touchInterceptor != null) {
val ret = touchInterceptor!!.onTouchEvent(this, event)
@ -74,4 +69,10 @@ class ExtendedSwipeRefreshLayout(context: Context, attrs: AttributeSet? = null)
onSizeChangedListener!!.onSizeChanged(this, w, h, oldw, oldh)
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
onApplySystemWindowInsetsListener?.onApplySystemWindowInsets(insets.systemWindowInsets)
return super.onApplyWindowInsets(insets)
}
}

View File

@ -19,12 +19,15 @@
package org.mariotaku.twidere.view
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.WindowInsets
import android.widget.ImageView
import org.mariotaku.ktextension.systemWindowInsets
import org.mariotaku.twidere.R
import org.mariotaku.twidere.view.iface.IExtendedView
@ -33,7 +36,7 @@ class ProfileBannerImageView(context: Context, attrs: AttributeSet) :
override var onSizeChangedListener: IExtendedView.OnSizeChangedListener? = null
override var touchInterceptor: IExtendedView.TouchInterceptor? = null
override var onFitSystemWindowsListener: IExtendedView.OnFitSystemWindowsListener? = null
override var onApplySystemWindowInsetsListener: IExtendedView.OnApplySystemWindowInsetsListener? = null
var bannerAspectRatio: Float = 0.toFloat()
@ -44,14 +47,6 @@ class ProfileBannerImageView(context: Context, attrs: AttributeSet) :
scaleType = ImageView.ScaleType.CENTER_CROP
}
@Deprecated("")
override fun fitSystemWindows(insets: Rect): Boolean {
if (onFitSystemWindowsListener != null) {
onFitSystemWindowsListener!!.onFitSystemWindows(insets)
}
return super.fitSystemWindows(insets)
}
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (touchInterceptor != null) {
val ret = touchInterceptor!!.dispatchTouchEvent(this, event)
@ -81,4 +76,10 @@ class ProfileBannerImageView(context: Context, attrs: AttributeSet) :
onSizeChangedListener!!.onSizeChanged(this, w, h, oldw, oldh)
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
onApplySystemWindowInsetsListener?.onApplySystemWindowInsets(insets.systemWindowInsets)
return super.onApplyWindowInsets(insets)
}
}

View File

@ -58,7 +58,7 @@ class TintedStatusFrameLayout(context: Context, attrs: AttributeSet? = null) :
setWillNotDraw(false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
ViewCompat.setOnApplyWindowInsetsListener(this) { v, insets ->
ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets ->
val top = insets.systemWindowInsetTop
val left = insets.systemWindowInsetLeft
val right = insets.systemWindowInsetRight

View File

@ -30,7 +30,7 @@ class SelectableUserViewHolder(
itemView: View,
adapter: SelectableUsersAdapter
) : SimpleUserViewHolder<SelectableUsersAdapter>(itemView, adapter) {
private val checkChangedListener = CompoundButton.OnCheckedChangeListener { view, value ->
private val checkChangedListener = CompoundButton.OnCheckedChangeListener { _, value ->
adapter.setItemChecked(layoutPosition, value)
}

View File

@ -27,10 +27,10 @@ interface IExtendedView {
var touchInterceptor: IExtendedView.TouchInterceptor?
var onSizeChangedListener: IExtendedView.OnSizeChangedListener?
var onFitSystemWindowsListener: IExtendedView.OnFitSystemWindowsListener?
var onApplySystemWindowInsetsListener: IExtendedView.OnApplySystemWindowInsetsListener?
interface OnFitSystemWindowsListener {
fun onFitSystemWindows(insets: Rect)
interface OnApplySystemWindowInsetsListener {
fun onApplySystemWindowInsets(insets: Rect)
}
interface OnSizeChangedListener {

View File

@ -22,8 +22,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
android:layout_height="match_parent">
<include
layout="@layout/activity_home_content"

View File

@ -18,9 +18,9 @@
-->
<android.support.v4.widget.SlidingPaneLayout
android:id="@+id/slidingPane"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/slidingPane"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -33,8 +33,10 @@
android:id="@+id/entriesList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:divider="@null"
android:dividerHeight="0dp"
android:scrollbarStyle="insideInset"
tools:listitem="@layout/list_item_preference_header_item"/>
</FrameLayout>

View File

@ -30,6 +30,11 @@
<item>Scale</item>
<item>Real size</item>
</string-array>
<string-array name="entries_navbar_style">
<item>Default</item>
<item>Transparent</item>
<item>Colored</item>
</string-array>
<string-array name="entries_notification_content">
<item>Home</item>
<item>Interactions</item>
@ -44,6 +49,13 @@
<item>Reverse proxy</item>
<!--<item>SOCKS</item>-->
</string-array>
<string-array name="entries_quick_access_shortcut_types">
<item>User</item>
<item>User timeline</item>
<item>User Favorites</item>
<item>List</item>
<item>List timeline</item>
</string-array>
<string-array name="entries_refresh_interval">
<item>3 minutes</item>
<item>5 minutes</item>
@ -74,13 +86,6 @@
<item>Pure white/black</item>
<item>Transparent</item>
</string-array>
<string-array name="entries_quick_access_shortcut_types">
<item>User</item>
<item>User timeline</item>
<item>User Favorites</item>
<item>List</item>
<item>List timeline</item>
</string-array>
<string-array name="entries_user_timeline_filter">
<item>Replies</item>
<item>Retweets</item>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--
~ Twidere - Twitter client for Android
~
@ -17,65 +17,63 @@
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<resources>
<string-array name="values_refresh_interval">
<item>3</item>
<item>5</item>
<item>10</item>
<item>15</item>
<item>30</item>
<item>60</item>
<item>120</item>
<item>240</item>
</string-array>
<string-array name="values_theme">
<item>light</item>
<item>dark</item>
<item>auto</item>
</string-array>
<string-array name="values_theme_background">
<item>default</item>
<item>solid</item>
<item>transparent</item>
<string-array name="dependency_values_false">
<item>false</item>
</string-array>
<string-array name="dependency_values_true">
<item>true</item>
</string-array>
<string-array name="dependency_values_false">
<item>false</item>
<string-array name="names_official_consumer_secret">
<!--Twitter for Android-->
<item>Twitter for Android</item>
<!--Twitter for iPhone-->
<item>Twitter for iPhone</item>
<!--Twitter for iPad-->
<item>Twitter for iPad</item>
<!--Twitter for Mac-->
<item>Twitter for Mac</item>
<!--Twitter for Windows Phone-->
<item>Twitter for Windows Phone</item>
<!--Twitter for Google TV-->
<item>Twitter for Google TV</item>
<!--TweetDeck-->
<item>TweetDeck</item>
</string-array>
<string-array name="values_tab_display_option">
<item>icon</item>
<item>label</item>
<item>both</item>
</string-array>
<string-array name="values_compose_now_action">
<item>compose</item>
<item>take_photo</item>
<item>pick_image</item>
</string-array>
<string-array name="values_media_preview_style">
<item>crop</item>
<item>scale</item>
<item>real_size</item>
<string-array name="types_official_consumer_secret">
<!--Twitter for Android-->
<item>TWITTER_FOR_ANDROID</item>
<!--Twitter for iPhone-->
<item>TWITTER_FOR_IPHONE</item>
<!--Twitter for iPad-->
<item>TWITTER_FOR_IPAD</item>
<!--Twitter for Mac-->
<item>TWITTER_FOR_MAC</item>
<!--Twitter for Windows Phone-->
<item>TWITTER_FOR_WINDOWS_PHONE</item>
<!--Twitter for Google TV-->
<item>TWITTER_FOR_GOOGLE_TV</item>
<!--TweetDeck-->
<item>TWEETDECK</item>
</string-array>
<string-array name="value_image_sources">
<item>camera</item>
<item>gallery</item>
<item>clipboard</item>
</string-array>
<string-array name="values_profile_image_style">
<item>round</item>
<item>square</item>
<string-array name="values_compose_location">
<item>none</item>
<item>place</item>
<item>coordinate</item>
</string-array>
<string-array name="values_proxy_type">
<item>http</item>
<item>reverse</item>
<!--<item>socks</item>-->
</string-array>
<string-array name="values_media_preload">
<item>wifi</item>
<string-array name="values_compose_now_action">
<item>compose</item>
<item>take_photo</item>
<item>pick_image</item>
</string-array>
<string-array name="values_home_refresh_content">
<item>mentions</item>
@ -83,32 +81,24 @@
<item>trends</item>
<item>saved_searches</item>
</string-array>
<string-array name="values_media_preload">
<item>wifi</item>
</string-array>
<string-array name="values_media_preview_style">
<item>crop</item>
<item>scale</item>
<item>real_size</item>
</string-array>
<string-array name="values_navbar_style">
<item>default</item>
<item>transparent</item>
<item>colored</item>
</string-array>
<string-array name="values_notification_content">
<item>home</item>
<item>mentions</item>
<item>inbox</item>
</string-array>
<string-array name="values_compose_location">
<item>none</item>
<item>place</item>
<item>coordinate</item>
</string-array>
<string-array name="values_tab_column_width">
<item>narrow</item>
<item>normal</item>
<item>wide</item>
</string-array>
<string-array name="values_quick_access_shortcut_types">
<item>user</item>
<item>user_timeline</item>
<item>user_favorites</item>
<item>list</item>
<item>list_timeline</item>
</string-array>
<string-array name="values_user_timeline_filter">
<item>replies</item>
<item>retweets</item>
</string-array>
<!-- CRC32 checksum of consumer secret of official clients to check whether user is using official keys -->
<string-array name="values_official_consumer_secret_crc32">
<!--Twitter for Android-->
@ -126,36 +116,54 @@
<!--TweetDeck-->
<item>ac602936</item>
</string-array>
<string-array name="names_official_consumer_secret">
<!--Twitter for Android-->
<item>Twitter for Android</item>
<!--Twitter for iPhone-->
<item>Twitter for iPhone</item>
<!--Twitter for iPad-->
<item>Twitter for iPad</item>
<!--Twitter for Mac-->
<item>Twitter for Mac</item>
<!--Twitter for Windows Phone-->
<item>Twitter for Windows Phone</item>
<!--Twitter for Google TV-->
<item>Twitter for Google TV</item>
<!--TweetDeck-->
<item>TweetDeck</item>
<string-array name="values_profile_image_style">
<item>round</item>
<item>square</item>
</string-array>
<string-array name="types_official_consumer_secret">
<!--Twitter for Android-->
<item>TWITTER_FOR_ANDROID</item>
<!--Twitter for iPhone-->
<item>TWITTER_FOR_IPHONE</item>
<!--Twitter for iPad-->
<item>TWITTER_FOR_IPAD</item>
<!--Twitter for Mac-->
<item>TWITTER_FOR_MAC</item>
<!--Twitter for Windows Phone-->
<item>TWITTER_FOR_WINDOWS_PHONE</item>
<!--Twitter for Google TV-->
<item>TWITTER_FOR_GOOGLE_TV</item>
<!--TweetDeck-->
<item>TWEETDECK</item>
<string-array name="values_proxy_type">
<item>http</item>
<item>reverse</item>
<!--<item>socks</item>-->
</string-array>
</resources>
<string-array name="values_quick_access_shortcut_types">
<item>user</item>
<item>user_timeline</item>
<item>user_favorites</item>
<item>list</item>
<item>list_timeline</item>
</string-array>
<string-array name="values_refresh_interval">
<item>3</item>
<item>5</item>
<item>10</item>
<item>15</item>
<item>30</item>
<item>60</item>
<item>120</item>
<item>240</item>
</string-array>
<string-array name="values_tab_column_width">
<item>narrow</item>
<item>normal</item>
<item>wide</item>
</string-array>
<string-array name="values_tab_display_option">
<item>icon</item>
<item>label</item>
<item>both</item>
</string-array>
<string-array name="values_theme">
<item>light</item>
<item>dark</item>
<item>auto</item>
</string-array>
<string-array name="values_theme_background">
<item>default</item>
<item>solid</item>
<item>transparent</item>
</string-array>
<string-array name="values_user_timeline_filter">
<item>replies</item>
<item>retweets</item>
</string-array>
</resources>

View File

@ -347,6 +347,7 @@
<string name="error_message_status_too_long">Tweet too long.</string>
<string name="error_message_tweet_shorten_failed">Tweet shorten failed.</string>
<string name="error_message_tweet_shortener_not_found">Tweet shortener not found, maybe it was uninstalled.</string>
<string name="error_message_video_upload_not_supported">Video upload not supported</string>
<string name="error_no_access_for_credentials">Your application can\'t access this resource.</string>
<string name="error_no_dm_permission">No direct message permission, check your Twitter application permission setting.</string>
<string name="error_title_device_incompatible">Incompatible device</string>
@ -872,6 +873,7 @@
<string name="preference_title_media_preload_non_metered_network">Preload on free network</string>
<string name="preference_title_multi_column_tab_width">Multi column tab width</string>
<string name="preference_title_multi_column_tabs">Multi column tabs</string>
<string name="preference_title_navbar_style">Navbar style</string>
<string name="preference_title_notification_ringtone">Ringtone</string>
<string name="preference_title_override_language">App language</string>
<string name="preference_title_portrait">Portrait</string>
@ -920,7 +922,7 @@
<!-- Normally you don't need to translate this -->
<string name="provider_default">Twidere</string>
<!-- Fanfou is a Chinese micro blogging website http://fanfou.com/ -->
<!-- Fanfou is a Chinese micro blogging website https://fanfou.com/ -->
<string name="provider_fanfou">Fanfou</string>
<string name="provider_gnusocial_de">GNU Social.de</string>
<string name="provider_gnusocial_net">GNU Social.net</string>
@ -1321,5 +1323,4 @@
<string name="users_blocked">Blocked these users.</string>
<string name="users_lists_with_name"><xliff:g id="name">%s</xliff:g>\'s lists</string>
<string name="users_statuses">User\'s tweets</string>
<string name="error_message_video_upload_not_supported">Video upload not supported</string>
</resources>

View File

@ -45,6 +45,20 @@
android:value="true"/>
</org.mariotaku.twidere.preference.ColorPickerPreference>
<org.mariotaku.twidere.preference.EntrySummaryListPreference
android:entries="@array/entries_navbar_style"
android:entryValues="@array/values_navbar_style"
android:key="navbar_style"
android:order="24"
android:title="@string/preference_title_navbar_style">
<extra
android:name="should_recreate"
android:value="true"/>
<extra
android:name="recreate_activity"
android:value="true"/>
</org.mariotaku.twidere.preference.EntrySummaryListPreference>
<org.mariotaku.twidere.preference.EmojiSupportPreference
android:key="emoji_support"
android:order="25"