Update 'README.md'

This commit is contained in:
esckey 2023-11-12 19:22:52 +01:00
parent 642643c9de
commit 3ed443814a
23 changed files with 279 additions and 277 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -1,6 +1,8 @@
[![Translate - with Weblate](https://img.shields.io/badge/translate%20with-Weblate-green.svg?style=flat)](https://weblate.tusky.app/) [![OpenCollective](https://opencollective.com/tusky/backers/badge.svg)](https://opencollective.com/tusky/) [![Build Status](https://app.bitrise.io/app/a3e773c3c57a894c/status.svg?token=qLu_Ti4Gp2LWcYT4eo2INQ&branch=develop)](https://app.bitrise.io/app/a3e773c3c57a894c)
# Tusky
[Prima versione debug Busky](https://zerbino.esiliati.org/#JERqHadYT8Ry7od9HgydmA,YHQI3znBO_gp-wt1qwg2dg,Tusky_23.0_113_642643c9_blue_debug.apk)
<img src="/fastlane/metadata/android/en-US/images/icon.png" width="120" height="120"/>
Tusky is a beautiful Android client for [Mastodon](https://github.com/mastodon/mastodon). Mastodon is an ActivityPub federated social network. That means no single entity controls the whole network, rather, like e-mail, volunteers and organisations operate their own independent servers, users from which can all interact with each other seamlessly.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -1,99 +1,99 @@
/* Copyright 2023 Andi McClure
*
* This file is a part of Tusky.
*
* 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.
*
* Tusky 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 Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.db
import android.content.Context
import android.content.DialogInterface
import android.util.Log
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.drafts.DraftsActivity
import kotlinx.coroutines.launch
import javax.inject.Inject
import javax.inject.Singleton
/**
* This class manages an alert popup when a post has failed and been saved to drafts.
* It must be separately registered in each lifetime in which it is to appear,
* and it only appears if the post failure belongs to the current user.
*/
private const val TAG = "DraftsAlert"
@Singleton
class DraftsAlert @Inject constructor(db: AppDatabase) {
// For tracking when a media upload fails in the service
private val draftDao: DraftDao = db.draftDao()
@Inject
lateinit var accountManager: AccountManager
fun <T> observeInContext(context: T, showAlert: Boolean) where T : Context, T : LifecycleOwner {
accountManager.activeAccount?.let { activeAccount ->
val coroutineScope = context.lifecycleScope
// Assume a single MainActivity, AccountActivity or DraftsActivity never sees more then one user id in its lifetime.
val activeAccountId = activeAccount.id
// This LiveData will be automatically disposed when the activity is destroyed.
val draftsNeedUserAlert = draftDao.draftsNeedUserAlert(activeAccountId)
// observe ensures that this gets called at the most appropriate moment wrt the context lifecycle—
// at init, at next onResume, or immediately if the context is resumed already.
if (showAlert) {
draftsNeedUserAlert.observe(context) { count ->
Log.d(TAG, "User id $activeAccountId changed: Notification-worthy draft count $count")
if (count > 0) {
AlertDialog.Builder(context)
.setTitle(R.string.action_post_failed)
.setMessage(
context.resources.getQuantityString(R.plurals.action_post_failed_detail, count)
)
.setPositiveButton(R.string.action_post_failed_show_drafts) { _: DialogInterface?, _: Int ->
clearDraftsAlert(coroutineScope, activeAccountId) // User looked at drafts
val intent = DraftsActivity.newIntent(context)
context.startActivity(intent)
}
.setNegativeButton(R.string.action_post_failed_do_nothing) { _: DialogInterface?, _: Int ->
clearDraftsAlert(coroutineScope, activeAccountId) // User doesn't care
}
.show()
}
}
} else {
draftsNeedUserAlert.observe(context) {
Log.d(TAG, "User id $activeAccountId: Clean out notification-worthy drafts")
clearDraftsAlert(coroutineScope, activeAccountId)
}
}
} ?: run {
Log.w(TAG, "Attempted to observe drafts, but there is no active account")
}
}
/**
* Clear drafts alert for specified user
*/
private fun clearDraftsAlert(coroutineScope: LifecycleCoroutineScope, id: Long) {
coroutineScope.launch {
draftDao.draftsClearNeedUserAlert(id)
}
}
}
/* Copyright 2023 Andi McClure
*
* This file is a part of Tusky.
*
* 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.
*
* Tusky 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 Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.db
import android.content.Context
import android.content.DialogInterface
import android.util.Log
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.drafts.DraftsActivity
import kotlinx.coroutines.launch
import javax.inject.Inject
import javax.inject.Singleton
/**
* This class manages an alert popup when a post has failed and been saved to drafts.
* It must be separately registered in each lifetime in which it is to appear,
* and it only appears if the post failure belongs to the current user.
*/
private const val TAG = "DraftsAlert"
@Singleton
class DraftsAlert @Inject constructor(db: AppDatabase) {
// For tracking when a media upload fails in the service
private val draftDao: DraftDao = db.draftDao()
@Inject
lateinit var accountManager: AccountManager
fun <T> observeInContext(context: T, showAlert: Boolean) where T : Context, T : LifecycleOwner {
accountManager.activeAccount?.let { activeAccount ->
val coroutineScope = context.lifecycleScope
// Assume a single MainActivity, AccountActivity or DraftsActivity never sees more then one user id in its lifetime.
val activeAccountId = activeAccount.id
// This LiveData will be automatically disposed when the activity is destroyed.
val draftsNeedUserAlert = draftDao.draftsNeedUserAlert(activeAccountId)
// observe ensures that this gets called at the most appropriate moment wrt the context lifecycle—
// at init, at next onResume, or immediately if the context is resumed already.
if (showAlert) {
draftsNeedUserAlert.observe(context) { count ->
Log.d(TAG, "User id $activeAccountId changed: Notification-worthy draft count $count")
if (count > 0) {
AlertDialog.Builder(context)
.setTitle(R.string.action_post_failed)
.setMessage(
context.resources.getQuantityString(R.plurals.action_post_failed_detail, count)
)
.setPositiveButton(R.string.action_post_failed_show_drafts) { _: DialogInterface?, _: Int ->
clearDraftsAlert(coroutineScope, activeAccountId) // User looked at drafts
val intent = DraftsActivity.newIntent(context)
context.startActivity(intent)
}
.setNegativeButton(R.string.action_post_failed_do_nothing) { _: DialogInterface?, _: Int ->
clearDraftsAlert(coroutineScope, activeAccountId) // User doesn't care
}
.show()
}
}
} else {
draftsNeedUserAlert.observe(context) {
Log.d(TAG, "User id $activeAccountId: Clean out notification-worthy drafts")
clearDraftsAlert(coroutineScope, activeAccountId)
}
}
} ?: run {
Log.w(TAG, "Attempted to observe drafts, but there is no active account")
}
}
/**
* Clear drafts alert for specified user
*/
private fun clearDraftsAlert(coroutineScope: LifecycleCoroutineScope, id: Long) {
coroutineScope.launch {
draftDao.draftsClearNeedUserAlert(id)
}
}
}

View file

@ -1,8 +1,8 @@
<!-- drawable/robot.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M12,2A2,2 0 0,1 14,4C14,4.74 13.6,5.39 13,5.73V7H14A7,7 0 0,1 21,14H22A1,1 0 0,1 23,15V18A1,1 0 0,1 22,19H21V20A2,2 0 0,1 19,22H5A2,2 0 0,1 3,20V19H2A1,1 0 0,1 1,18V15A1,1 0 0,1 2,14H3A7,7 0 0,1 10,7H11V5.73C10.4,5.39 10,4.74 10,4A2,2 0 0,1 12,2M7.5,13A2.5,2.5 0 0,0 5,15.5A2.5,2.5 0 0,0 7.5,18A2.5,2.5 0 0,0 10,15.5A2.5,2.5 0 0,0 7.5,13M16.5,13A2.5,2.5 0 0,0 14,15.5A2.5,2.5 0 0,0 16.5,18A2.5,2.5 0 0,0 19,15.5A2.5,2.5 0 0,0 16.5,13Z" />
<!-- drawable/robot.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M12,2A2,2 0 0,1 14,4C14,4.74 13.6,5.39 13,5.73V7H14A7,7 0 0,1 21,14H22A1,1 0 0,1 23,15V18A1,1 0 0,1 22,19H21V20A2,2 0 0,1 19,22H5A2,2 0 0,1 3,20V19H2A1,1 0 0,1 1,18V15A1,1 0 0,1 2,14H3A7,7 0 0,1 10,7H11V5.73C10.4,5.39 10,4.74 10,4A2,2 0 0,1 12,2M7.5,13A2.5,2.5 0 0,0 5,15.5A2.5,2.5 0 0,0 7.5,18A2.5,2.5 0 0,0 10,15.5A2.5,2.5 0 0,0 7.5,13M16.5,13A2.5,2.5 0 0,0 14,15.5A2.5,2.5 0 0,0 16.5,18A2.5,2.5 0 0,0 19,15.5A2.5,2.5 0 0,0 16.5,13Z" />
</vector>

View file

@ -1,8 +1,8 @@
<!-- drawable/account_remove.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M15,14C17.67,14 23,15.33 23,18V20H7V18C7,15.33 12.33,14 15,14M15,12A4,4 0 0,1 11,8A4,4 0 0,1 15,4A4,4 0 0,1 19,8A4,4 0 0,1 15,12M5,9.59L7.12,7.46L8.54,8.88L6.41,11L8.54,13.12L7.12,14.54L5,12.41L2.88,14.54L1.46,13.12L3.59,11L1.46,8.88L2.88,7.46L5,9.59Z" />
<!-- drawable/account_remove.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M15,14C17.67,14 23,15.33 23,18V20H7V18C7,15.33 12.33,14 15,14M15,12A4,4 0 0,1 11,8A4,4 0 0,1 15,4A4,4 0 0,1 19,8A4,4 0 0,1 15,12M5,9.59L7.12,7.46L8.54,8.88L6.41,11L8.54,13.12L7.12,14.54L5,12.41L2.88,14.54L1.46,13.12L3.59,11L1.46,8.88L2.88,7.46L5,9.59Z" />
</vector>

View file

@ -1,159 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- This file is "magic". Simply by existing in Tusky at this path, it overrides
the media3 default layout. This version is adapted from media3-ui-1.1.0. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 0dp dimensions are used to prevent this view from influencing the size of
the parent view if it uses "wrap_content". It is expanded to occupy the
entirety of the parent in code, after the parent's size has been
determined. See: https://github.com/google/ExoPlayer/issues/8726.
-->
<!-- Change from media3 default: hide "dark curtain" background element -->
<!--
<View android:id="@id/exo_controls_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/exo_black_opacity_60"/>
-->
<!-- Changes from media3 default: Background is gray rather than transparent; moved before (underneath on Z axis) exo_bottom_bar -->
<LinearLayout
android:id="@id/exo_center_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@color/exo_bottom_bar_background"
android:gravity="center"
android:padding="@dimen/exo_styled_controls_padding"
android:clipToPadding="false"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_prev"
style="@style/ExoStyledControls.Button.Center.Previous"/>
<include layout="@layout/exo_player_control_rewind_button" />
<!-- Changes from media3 default: Different style to add more margins -->
<ImageButton android:id="@id/exo_play_pause"
style="@style/TuskyExoPlayerPlayPause"/>
<include layout="@layout/exo_player_control_ffwd_button" />
<ImageButton android:id="@id/exo_next"
style="@style/ExoStyledControls.Button.Center.Next"/>
</LinearLayout>
<FrameLayout android:id="@id/exo_bottom_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/exo_styled_bottom_bar_height"
android:layout_marginTop="@dimen/exo_styled_bottom_bar_margin_top"
android:layout_gravity="bottom"
android:background="@color/exo_bottom_bar_background"
android:layoutDirection="ltr">
<LinearLayout android:id="@id/exo_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingEnd="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingLeft="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingRight="@dimen/exo_styled_bottom_bar_time_padding"
android:layout_gravity="center_vertical|start"
android:layoutDirection="ltr">
<TextView android:id="@id/exo_position"
style="@style/ExoStyledControls.TimeText.Position"/>
<TextView
style="@style/ExoStyledControls.TimeText.Separator"/>
<TextView android:id="@id/exo_duration"
style="@style/ExoStyledControls.TimeText.Duration"/>
</LinearLayout>
<LinearLayout android:id="@id/exo_basic_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_vr"
style="@style/ExoStyledControls.Button.Bottom.VR"/>
<ImageButton android:id="@id/exo_shuffle"
style="@style/ExoStyledControls.Button.Bottom.Shuffle"/>
<ImageButton android:id="@id/exo_repeat_toggle"
style="@style/ExoStyledControls.Button.Bottom.RepeatToggle"/>
<ImageButton android:id="@id/exo_subtitle"
style="@style/ExoStyledControls.Button.Bottom.CC"/>
<ImageButton android:id="@id/exo_settings"
style="@style/ExoStyledControls.Button.Bottom.Settings"/>
<ImageButton android:id="@id/exo_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
<ImageButton android:id="@id/exo_overflow_show"
style="@style/ExoStyledControls.Button.Bottom.OverflowShow"/>
</LinearLayout>
<HorizontalScrollView android:id="@id/exo_extra_controls_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:visibility="invisible">
<LinearLayout android:id="@id/exo_extra_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_overflow_hide"
style="@style/ExoStyledControls.Button.Bottom.OverflowHide"/>
</LinearLayout>
</HorizontalScrollView>
</FrameLayout>
<View android:id="@id/exo_progress_placeholder"
android:layout_width="match_parent"
android:layout_height="@dimen/exo_styled_progress_layout_height"
android:layout_gravity="bottom"
android:layout_marginBottom="@dimen/exo_styled_progress_margin_bottom"/>
<LinearLayout android:id="@id/exo_minimal_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="@dimen/exo_styled_minimal_controls_margin_bottom"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_minimal_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
</LinearLayout>
</merge>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- This file is "magic". Simply by existing in Tusky at this path, it overrides
the media3 default layout. This version is adapted from media3-ui-1.1.0. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 0dp dimensions are used to prevent this view from influencing the size of
the parent view if it uses "wrap_content". It is expanded to occupy the
entirety of the parent in code, after the parent's size has been
determined. See: https://github.com/google/ExoPlayer/issues/8726.
-->
<!-- Change from media3 default: hide "dark curtain" background element -->
<!--
<View android:id="@id/exo_controls_background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/exo_black_opacity_60"/>
-->
<!-- Changes from media3 default: Background is gray rather than transparent; moved before (underneath on Z axis) exo_bottom_bar -->
<LinearLayout
android:id="@id/exo_center_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@color/exo_bottom_bar_background"
android:gravity="center"
android:padding="@dimen/exo_styled_controls_padding"
android:clipToPadding="false"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_prev"
style="@style/ExoStyledControls.Button.Center.Previous"/>
<include layout="@layout/exo_player_control_rewind_button" />
<!-- Changes from media3 default: Different style to add more margins -->
<ImageButton android:id="@id/exo_play_pause"
style="@style/TuskyExoPlayerPlayPause"/>
<include layout="@layout/exo_player_control_ffwd_button" />
<ImageButton android:id="@id/exo_next"
style="@style/ExoStyledControls.Button.Center.Next"/>
</LinearLayout>
<FrameLayout android:id="@id/exo_bottom_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/exo_styled_bottom_bar_height"
android:layout_marginTop="@dimen/exo_styled_bottom_bar_margin_top"
android:layout_gravity="bottom"
android:background="@color/exo_bottom_bar_background"
android:layoutDirection="ltr">
<LinearLayout android:id="@id/exo_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingEnd="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingLeft="@dimen/exo_styled_bottom_bar_time_padding"
android:paddingRight="@dimen/exo_styled_bottom_bar_time_padding"
android:layout_gravity="center_vertical|start"
android:layoutDirection="ltr">
<TextView android:id="@id/exo_position"
style="@style/ExoStyledControls.TimeText.Position"/>
<TextView
style="@style/ExoStyledControls.TimeText.Separator"/>
<TextView android:id="@id/exo_duration"
style="@style/ExoStyledControls.TimeText.Duration"/>
</LinearLayout>
<LinearLayout android:id="@id/exo_basic_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_vr"
style="@style/ExoStyledControls.Button.Bottom.VR"/>
<ImageButton android:id="@id/exo_shuffle"
style="@style/ExoStyledControls.Button.Bottom.Shuffle"/>
<ImageButton android:id="@id/exo_repeat_toggle"
style="@style/ExoStyledControls.Button.Bottom.RepeatToggle"/>
<ImageButton android:id="@id/exo_subtitle"
style="@style/ExoStyledControls.Button.Bottom.CC"/>
<ImageButton android:id="@id/exo_settings"
style="@style/ExoStyledControls.Button.Bottom.Settings"/>
<ImageButton android:id="@id/exo_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
<ImageButton android:id="@id/exo_overflow_show"
style="@style/ExoStyledControls.Button.Bottom.OverflowShow"/>
</LinearLayout>
<HorizontalScrollView android:id="@id/exo_extra_controls_scroll_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:visibility="invisible">
<LinearLayout android:id="@id/exo_extra_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_overflow_hide"
style="@style/ExoStyledControls.Button.Bottom.OverflowHide"/>
</LinearLayout>
</HorizontalScrollView>
</FrameLayout>
<View android:id="@id/exo_progress_placeholder"
android:layout_width="match_parent"
android:layout_height="@dimen/exo_styled_progress_layout_height"
android:layout_gravity="bottom"
android:layout_marginBottom="@dimen/exo_styled_progress_margin_bottom"/>
<LinearLayout android:id="@id/exo_minimal_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="@dimen/exo_styled_minimal_controls_margin_bottom"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layoutDirection="ltr">
<ImageButton android:id="@id/exo_minimal_fullscreen"
style="@style/ExoStyledControls.Button.Bottom.FullScreen"/>
</LinearLayout>
</merge>

View file

@ -1,6 +1,6 @@
<resources>
<plurals name="action_post_failed_detail">
<item quantity="one">@string/action_post_failed_detail</item>
<item quantity="other">@string/action_post_failed_detail_plural</item>
</plurals>
<resources>
<plurals name="action_post_failed_detail">
<item quantity="one">@string/action_post_failed_detail</item>
<item quantity="other">@string/action_post_failed_detail_plural</item>
</plurals>
</resources>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 KiB

After

Width:  |  Height:  |  Size: 673 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 842 KiB

After

Width:  |  Height:  |  Size: 842 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 KiB

After

Width:  |  Height:  |  Size: 620 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 928 KiB

After

Width:  |  Height:  |  Size: 928 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 317 KiB