Merge branch 'develop' into translatewiki

# Conflicts:
#	core/src/main/res/values-ar/strings.xml
This commit is contained in:
Sean Mac Gillicuddy 2020-03-12 16:59:23 +00:00
commit 2cf774e51b
67 changed files with 4215 additions and 1205 deletions

View File

@ -29,13 +29,11 @@ jobs:
with:
api-level: ${{ matrix.api-level }}
arch: x86_64
script: bash instrumentation.sh
script: bash contrib/instrumentation.sh
- name: create unit coverage
run: ./gradlew jacocoTestDebugUnitTestReport jacocoTestCustomExampleDebugUnitTestReport
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
run: |
bash <(curl -s https://codecov.io/bash) -t ${{ secrets.CODECOV_TOKEN }}

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,8 @@
<application
android:name=".KiwixApp"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round">
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<activity
android:name=".splash.KiwixSplashActivity"
android:label="@string/app_name"

View File

@ -177,6 +177,8 @@ class ZimHostActivity : BaseActivity(), ZimHostCallbacks, ZimHostContract.View {
if (ServerUtils.isServerStarted) {
ip = ServerUtils.getSocketAddress()
layoutServerStarted()
} else {
layoutServerStopped()
}
}

View File

@ -81,7 +81,7 @@ public class HotspotService extends Service
intent.getStringArrayListExtra(SELECTED_ZIM_PATHS_KEY))) {
zimHostCallbacks.onServerStarted(ServerUtils.getSocketAddress());
startForegroundNotificationHelper();
Toast.makeText(this, R.string.server_started__successfully_toast_message,
Toast.makeText(this, R.string.server_started_successfully_toast_message,
Toast.LENGTH_SHORT).show();
} else {
zimHostCallbacks.onServerFailedToStart();
@ -90,6 +90,8 @@ public class HotspotService extends Service
break;
case ACTION_STOP_SERVER:
Toast.makeText(this, R.string.server_stopped_successfully_toast_message,
Toast.LENGTH_SHORT).show();
stopHotspotAndDismissNotification();
break;

View File

@ -20,8 +20,6 @@ package org.kiwix.kiwixmobile.zim_manager.fileselect_view
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -157,8 +155,7 @@ class ZimFileSelectFragment : BaseFragment() {
if (ContextCompat.checkSelfPermission(
activity!!,
Manifest.permission.READ_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED &&
VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN
) != PackageManager.PERMISSION_GRANTED
) {
context.toast(R.string.request_storage)
requestPermissions(

View File

@ -137,6 +137,7 @@ class LibraryFragment : BaseFragment() {
libraryErrorText.setText(R.string.no_network_connection)
libraryErrorText.visibility = VISIBLE
}
librarySwipeRefresh.isRefreshing = false
}
}
}

View File

@ -15,18 +15,17 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:background="@android:color/transparent"
android:paddingLeft="5dp"
android:paddingStart="5dp"
android:paddingTop="5dp"
android:paddingRight="5dp"
android:paddingEnd="5dp"
android:paddingBottom="1dp"
android:text="@string/your_device"
android:textSize="13sp"
android:textStyle="italic"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_bar" />
<TextView
@ -34,17 +33,16 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:background="@android:color/transparent"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:paddingBottom="5dp"
android:textIsSelectable="true"
android:textSize="17sp"
android:textStyle="bold"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_your_device"
tools:hint="Device Name" />
@ -52,11 +50,11 @@
android:id="@+id/view_device_list_boundary"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:background="@color/accent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_device_name" />
<TextView
@ -69,8 +67,8 @@
android:text="@string/nearby_devices"
android:textSize="16sp"
app:fontFamily="monospace"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/view_device_list_boundary" />
<androidx.recyclerview.widget.RecyclerView
@ -79,8 +77,8 @@
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:visibility="invisible"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device"
app:layout_constraintVertical_bias="0.0" />
@ -92,8 +90,8 @@
android:background="@android:color/transparent"
android:gravity="center"
android:text="@string/no_devices_found"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device" />
<ProgressBar
@ -104,21 +102,21 @@
android:background="@android:color/transparent"
android:indeterminate="true"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device" />
<View
android:id="@+id/view_file_list_boundary"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="200dp"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:background="@color/accent"
app:layout_constraintBottom_toTopOf="@+id/text_view_files_for_transfer"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_available_device" />
<TextView
@ -132,8 +130,8 @@
android:textSize="16sp"
app:fontFamily="monospace"
app:layout_constraintBottom_toTopOf="@id/recycler_view_transfer_files"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/view_file_list_boundary" />
<androidx.recyclerview.widget.RecyclerView
@ -142,8 +140,8 @@
android:layout_height="0dp"
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_view_files_for_transfer" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -14,7 +14,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:text="@string/server_textview_default_message"
app:layout_constraintStart_toStartOf="parent"
@ -28,8 +27,8 @@
android:layout_marginBottom="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="@+id/startServerButton"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/serverTextView" />
<Button

View File

@ -6,16 +6,16 @@
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin">
android:paddingEnd="@dimen/activity_horizontal_margin">
<ImageView
android:id="@+id/libraryDownloadFavicon"
android:layout_width="@dimen/favicon_width"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginRight="@dimen/favicon_margin_right"
android:layout_marginEnd="@dimen/favicon_margin_right"
android:adjustViewBounds="true"
android:minHeight="?android:attr/listPreferredItemHeight"
android:scaleType="fitCenter"
@ -85,8 +85,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/stop_horizontal_margin"
android:layout_marginRight="@dimen/stop_horizontal_margin"
android:layout_marginStart="@dimen/stop_horizontal_margin"
android:layout_marginEnd="@dimen/stop_horizontal_margin"
android:layout_weight="0.5"
android:minWidth="@dimen/stop_min_width"
android:minHeight="@dimen/stop_min_height"

View File

@ -7,8 +7,11 @@
android:padding="24dp">
<ImageView
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_max="160dp"
app:layout_constraintWidth_max="160dp"
android:scaleType="fitCenter"
android:contentDescription="@string/kiwi"
android:src="@drawable/kiwix_icon_with_title"
app:layout_constraintBottom_toTopOf="@id/heading"

View File

@ -8,8 +8,10 @@
<ImageView
android:id="@+id/airplane"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintHeight_max="121dp"
android:scaleType="fitCenter"
android:alpha="1.0"
android:contentDescription="@string/save_books_offline"
android:visibility="invisible"

View File

@ -13,8 +13,8 @@
android:id="@+id/libraryBookFavicon"
android:layout_width="@dimen/favicon_width"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/favicon_margin_right"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/favicon_margin_right"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@mipmap/ic_launcher"
@ -28,7 +28,7 @@
style="@style/list_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/favicon_margin_right"
android:layout_marginStart="@dimen/favicon_margin_right"
android:layout_marginTop="@dimen/activity_horizontal_margin"
app:layout_constraintStart_toEndOf="@+id/libraryBookFavicon"
app:layout_constraintTop_toTopOf="parent"
@ -39,7 +39,7 @@
style="@style/list_item_body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/libraryBookTitle"
app:layout_constraintTop_toBottomOf="@+id/libraryBookTitle"
@ -79,7 +79,7 @@
style="@style/list_item_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/libraryBookSize"
tools:text="Date" />

View File

@ -12,15 +12,15 @@
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:gravity="center_vertical"
android:paddingLeft="5dp"
android:paddingStart="5dp"
android:paddingTop="1dp"
android:paddingRight="5dp"
android:paddingEnd="5dp"
android:paddingBottom="1dp"
android:textIsSelectable="true"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:hint="File name" />
@ -29,16 +29,15 @@
android:layout_width="wrap_content"
android:layout_height="0dp"
android:background="@android:color/transparent"
android:paddingLeft="5dp"
android:paddingStart="5dp"
android:paddingTop="1dp"
android:paddingEnd="5dp"
android:paddingRight="5dp"
android:paddingBottom="1dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toRightOf="@id/text_view_file_item_name"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toEndOf="@id/text_view_file_item_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
@ -46,18 +45,16 @@
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:background="@android:color/transparent"
android:contentDescription="@string/status"
android:paddingLeft="5dp"
android:paddingStart="5dp"
android:paddingTop="1dp"
android:paddingEnd="5dp"
android:paddingRight="5dp"
android:paddingBottom="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintLeft_toRightOf="@id/text_view_file_item_name"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toEndOf="@id/text_view_file_item_name"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_baseline_wait_24px" />

View File

@ -4,9 +4,9 @@
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/dimen_medium_padding">
<TextView

View File

@ -13,9 +13,9 @@
android:layout_weight="3"
android:background="@android:color/transparent"
android:gravity="center_horizontal"
android:paddingLeft="5dp"
android:paddingStart="5dp"
android:paddingTop="1dp"
android:paddingRight="5dp"
android:paddingEnd="5dp"
android:paddingBottom="1dp"
android:textIsSelectable="false"
android:textSize="17sp"

View File

@ -20,7 +20,7 @@ import org.gradle.api.JavaVersion
object Config {
const val compileSdk = 28
const val minSdk = 15
const val minSdk = 17
const val targetSdk = 28
val javaVersion = JavaVersion.VERSION_1_8
}

Binary file not shown.

View File

@ -0,0 +1,171 @@
/*
* Kiwix Android
* Copyright (c) 2020 Kiwix <android.kiwix.org>
* 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/>.
*
*/
/**
* USAGE:
* Cuts string resources with the name arg3 from the module from arg1
* and pastes them to the string resources from the module from arg2.
*
* Example usage:
* kotlinc -script move-string-resource.kts ../app ../core history_from_current_book
*
* This will cut all strings with the name history_from_current_book from
* all strings.xml files within directories with a prefix of values*
* in ../app/src/main/res/ and paste them into
* their corresponding files within ../core/src/main/res/values*.
*
*/
/**
* To recompile script to binary use kscript:
* https://github.com/holgerbrandl/kscript
* https://github.com/holgerbrandl/kscript#deploy-scripts-as-standalone-binaries
*/
import java.io.File
import java.lang.StringBuilder
import kotlin.system.exitProcess
if (args.size < 3) {
printCorrectUsageAndExit()
}
val pathToValues = "/src/main/res/"
val source = args[0]
val destination = args[1]
val key = """name="${args[2]}""""
val sourceDir = File(source + pathToValues)
if (!sourceDir.exists()) {
printModuleIsNotValidDir(source, pathToValues)
}
println("\nRunning transfer of string resources...\n")
val numberOfCutLines = sourceDir.cutStringResourcesAndPasteToDestination(key, source, destination)
println("\nTransfer of string resources complete. Moved $numberOfCutLines strings.")
fun File.cutStringResourcesAndPasteToDestination(key: String, source: String, destination: String) : Int {
var numberOfCutLines = 0
this.walk().filter { it.name.equals("strings.xml") }.forEach { resourceFile ->
cutLineFromResourceFile(resourceFile, key).takeIf{ it.isNotEmpty() }?.let{ cutLine ->
pasteLineToDestination(
openOrCreateDestinationResourceFile(resourceFile, source, destination),
cutLine
)
numberOfCutLines++
}
}
return numberOfCutLines
}
fun openOrCreateDestinationResourceFile(resourceFile: File, source: String, destination: String): File {
val destinationFilePath = resourceFile.path.replaceRange(0..source.length, destination + "/")
val destinationFile = File(destinationFilePath)
val destinationDirectory = destinationFile.parentFile
if (!destinationDirectory.exists()) {
createDestinationDirectoryAndFile(destinationDirectory, destinationFile)
}
return destinationFile
}
fun createDestinationDirectoryAndFile(destinationDirectory: File, destinationFile: File) {
destinationDirectory.mkdirs()
val isNewFileCreated: Boolean = destinationFile.createNewFile()
if (!isNewFileCreated) {
System.err.println("Could not create resource file ${destinationFile.path}")
System.exit(-1)
}
destinationFile.writeText(
"""
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<resources>
</resources>
""".trimIndent()
)
println("Created directory ${destinationDirectory.path} and resource file ${destinationFile.path}")
}
fun pasteLineToDestination(destinationFile: File, cutLine: String) {
var resourceDataWithPastedLine = StringBuilder()
destinationFile.forEachLine { line ->
resourceDataWithPastedLine.appendln(line)
if (line.contains("<resources")) {
printPastedValue(cutLine, destinationFile)
resourceDataWithPastedLine.appendln(cutLine)
}
}
destinationFile.writeText(resourceDataWithPastedLine.toString())
}
fun cutLineFromResourceFile(resourceFile: File, key: String): String {
var resourceDataWithoutCutLine = StringBuilder()
var cutLine: String = ""
resourceFile.forEachLine { line ->
if (line.contains(key)) {
cutLine = line
printCutValueAndPath(cutLine, resourceFile)
} else {
resourceDataWithoutCutLine.appendln(line)
}
}
resourceFile.writeText(resourceDataWithoutCutLine.toString())
return cutLine
}
fun printCorrectUsageAndExit() {
System.err.println("Usage:\nmove-string-resource.kts [source module] [destination module] [string key]")
printExample()
exitProcess(-1)
}
fun printModuleIsNotValidDir(source: String, pathToValues: String) {
System.err.println("$source$pathToValues is not a valid directory.")
printExample()
exitProcess(-1)
}
fun printExample() {
System.err.println("Example when copying strings with key kiwi from app to core:")
System.err.println("move-string-resource.kts ../app ../core kiwi")
}
fun printPastedValue(key: String, resourceFile: File) {
println("Wrote string $key to ${resourceFile.path}")
}
fun printCutValueAndPath(key: String, resourceFile: File) {
println("Cut string $key from ${resourceFile.path}")
}
fun addNewLine(firstLineRead: Boolean, stringToAddLineTo: String, line: String): String {
var tempString = stringToAddLineTo
if (firstLineRead) {
tempString = tempString + "\n"
}
tempString = tempString + line
return tempString
}

0
testdroid.py → contrib/testdroid.py Executable file → Normal file
View File

0
upload-apk.py → contrib/upload-apk.py Executable file → Normal file
View File

View File

@ -138,9 +138,6 @@ public abstract class CoreApp extends Application {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
builder.detectFileUriExposure();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
builder.detectLeakedRegistrationObjects();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
builder.detectNonSdkApiUsage();
}
@ -148,6 +145,7 @@ public abstract class CoreApp extends Application {
.detectLeakedClosableObjects()
.detectLeakedSqlLiteObjects()
.penaltyLog()
.detectLeakedRegistrationObjects()
.build();
}

View File

@ -37,6 +37,8 @@ import butterknife.BindView;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import org.kiwix.kiwixmobile.core.Intents;
import org.kiwix.kiwixmobile.core.R;
import org.kiwix.kiwixmobile.core.R2;
@ -45,6 +47,8 @@ import org.kiwix.kiwixmobile.core.di.components.CoreComponent;
import org.kiwix.kiwixmobile.core.extensions.ImageViewExtensionsKt;
import org.kiwix.kiwixmobile.core.main.CoreMainActivity;
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer;
import org.kiwix.kiwixmobile.core.utils.DialogShower;
import org.kiwix.kiwixmobile.core.utils.KiwixDialog;
import static org.kiwix.kiwixmobile.core.utils.Constants.EXTRA_CHOSE_X_FILE;
import static org.kiwix.kiwixmobile.core.utils.Constants.EXTRA_CHOSE_X_TITLE;
@ -69,6 +73,8 @@ public class BookmarksActivity extends BaseActivity implements BookmarksContract
BookmarksContract.Presenter presenter;
@Inject
ZimReaderContainer zimReaderContainer;
@Inject
DialogShower dialogShower;
private boolean refreshAdapter = true;
private BookmarksAdapter bookmarksAdapter;
@ -117,7 +123,7 @@ public class BookmarksActivity extends BaseActivity implements BookmarksContract
};
@Override protected void injection(CoreComponent coreComponent) {
coreComponent.inject(this);
coreComponent.activityComponentBuilder().activity(this).build().inject(this);
}
@Override
@ -195,11 +201,14 @@ public class BookmarksActivity extends BaseActivity implements BookmarksContract
onBackPressed();
return true;
} else if (itemId == R.id.menu_bookmarks_clear) {
presenter.deleteBookmarks(new ArrayList<>(allBookmarks));
allBookmarks.clear();
bookmarksList.clear();
bookmarksAdapter.notifyDataSetChanged();
Toast.makeText(this, R.string.all_bookmarks_cleared_toast, Toast.LENGTH_SHORT).show();
dialogShower.show(KiwixDialog.DeleteBookmarks.INSTANCE, (Function0<Unit>) () -> {
presenter.deleteBookmarks(new ArrayList<>(allBookmarks));
allBookmarks.clear();
bookmarksList.clear();
bookmarksAdapter.notifyDataSetChanged();
Toast.makeText(this, R.string.all_bookmarks_cleared_toast, Toast.LENGTH_SHORT).show();
return Unit.INSTANCE;
});
return true;
}
return super.onOptionsItemSelected(item);

View File

@ -15,24 +15,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.bookmark
package org.kiwix.kiwixmobile.core.bookmark;
import org.kiwix.kiwixmobile.core.base.BaseContract
import java.util.List;
import org.kiwix.kiwixmobile.core.base.BaseContract;
interface BookmarksContract {
interface View extends BaseContract.View<Presenter> {
void updateBookmarksList(List<BookmarkItem> bookmarks);
void notifyBookmarksListFiltered(List<BookmarkItem> bookmarks);
internal interface BookmarksContract {
interface View : BaseContract.View<Presenter> {
fun updateBookmarksList(bookmarks: List<BookmarkItem>)
fun notifyBookmarksListFiltered(bookmarks: List<BookmarkItem>)
}
interface Presenter extends BaseContract.Presenter<View> {
void loadBookmarks(boolean showBookmarksCurrentBook);
void filterBookmarks(List<BookmarkItem> bookmarksList, String newText);
void deleteBookmarks(List<BookmarkItem> deleteList);
interface Presenter : BaseContract.Presenter<View> {
fun loadBookmarks(showBookmarksCurrentBook: Boolean)
fun filterBookmarks(bookmarksList: List<BookmarkItem>, newText: String)
fun deleteBookmarks(deleteList: List<BookmarkItem>)
}
}

View File

@ -21,8 +21,10 @@ package org.kiwix.kiwixmobile.core.di.components
import android.app.Activity
import dagger.BindsInstance
import dagger.Subcomponent
import org.kiwix.kiwixmobile.core.bookmark.BookmarksActivity
import org.kiwix.kiwixmobile.core.di.ActivityScope
import org.kiwix.kiwixmobile.core.di.modules.ActivityModule
import org.kiwix.kiwixmobile.core.history.HistoryActivity
import org.kiwix.kiwixmobile.core.search.SearchActivity
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.ShowDeleteSearchDialog
import org.kiwix.kiwixmobile.core.settings.CorePrefsFragment
@ -33,6 +35,8 @@ interface CoreActivityComponent {
fun inject(searchActivity: SearchActivity)
fun inject(showDeleteSearchDialog: ShowDeleteSearchDialog)
fun inject(corePrefsFragment: CorePrefsFragment)
fun inject(historyActivity: HistoryActivity)
fun inject(bookmarksActivity: BookmarksActivity)
@Subcomponent.Builder
interface Builder {

View File

@ -26,7 +26,6 @@ import dagger.Component
import eu.mhutti1.utils.storage.StorageSelectDialog
import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.StorageObserver
import org.kiwix.kiwixmobile.core.bookmark.BookmarksActivity
import org.kiwix.kiwixmobile.core.bookmark.BookmarksModule
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.dao.NewBookDao
@ -46,7 +45,6 @@ import org.kiwix.kiwixmobile.core.di.modules.SearchModule
import org.kiwix.kiwixmobile.core.downloader.Downloader
import org.kiwix.kiwixmobile.core.error.ErrorActivity
import org.kiwix.kiwixmobile.core.help.HelpActivity
import org.kiwix.kiwixmobile.core.history.HistoryActivity
import org.kiwix.kiwixmobile.core.history.HistoryModule
import org.kiwix.kiwixmobile.core.main.AddNoteDialog
import org.kiwix.kiwixmobile.core.main.KiwixWebView
@ -112,7 +110,5 @@ interface CoreComponent {
fun inject(errorActivity: ErrorActivity)
fun inject(searchActivity: SearchActivity)
fun inject(helpActivity: HelpActivity)
fun inject(historyActivity: HistoryActivity)
fun inject(bookmarksActivity: BookmarksActivity)
fun inject(settingsActivity: CoreSettingsActivity)
}

View File

@ -39,6 +39,8 @@ import butterknife.BindView;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import org.kiwix.kiwixmobile.core.Intents;
import org.kiwix.kiwixmobile.core.R;
import org.kiwix.kiwixmobile.core.R2;
@ -47,6 +49,8 @@ import org.kiwix.kiwixmobile.core.di.components.CoreComponent;
import org.kiwix.kiwixmobile.core.extensions.ImageViewExtensionsKt;
import org.kiwix.kiwixmobile.core.main.CoreMainActivity;
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer;
import org.kiwix.kiwixmobile.core.utils.DialogShower;
import org.kiwix.kiwixmobile.core.utils.KiwixDialog;
import static org.kiwix.kiwixmobile.core.utils.Constants.EXTRA_CHOSE_X_FILE;
import static org.kiwix.kiwixmobile.core.utils.Constants.EXTRA_CHOSE_X_URL;
@ -66,6 +70,8 @@ public class HistoryActivity extends BaseActivity implements HistoryContract.Vie
HistoryContract.Presenter presenter;
@Inject
ZimReaderContainer zimReaderContainer;
@Inject
DialogShower dialogShower;
@BindView(R2.id.recycler_view)
RecyclerView recyclerView;
@BindView(R2.id.no_history)
@ -93,26 +99,29 @@ public class HistoryActivity extends BaseActivity implements HistoryContract.Vie
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
refreshAdapter = false;
if (item.getItemId() == R.id.menu_context_delete) {
fullHistory.removeAll(deleteList);
for (HistoryListItem history : deleteList) {
int position = historyList.indexOf(history);
dialogShower.show(KiwixDialog.DeleteHistory.INSTANCE, (Function0<Unit>) () -> {
fullHistory.removeAll(deleteList);
for (HistoryListItem history : deleteList) {
int position = historyList.indexOf(history);
/*
Delete the current category header if there are no items after the current one or
if the item being removed is between two category headers.
*/
if (position - 1 >= 0 && historyList.get(position - 1) == null &&
(position + 1 >= historyList.size() ||
(position + 1 < historyList.size() && historyList.get(position + 1) == null))) {
historyList.remove(position - 1);
historyAdapter.notifyItemRemoved(position - 1);
if (position - 1 >= 0 && historyList.get(position - 1) == null &&
(position + 1 >= historyList.size() ||
(position + 1 < historyList.size() && historyList.get(position + 1) == null))) {
historyList.remove(position - 1);
historyAdapter.notifyItemRemoved(position - 1);
}
position = historyList.indexOf(history);
historyList.remove(history);
historyAdapter.notifyItemRemoved(position);
historyAdapter.notifyItemRangeChanged(position, historyAdapter.getItemCount());
}
position = historyList.indexOf(history);
historyList.remove(history);
historyAdapter.notifyItemRemoved(position);
historyAdapter.notifyItemRangeChanged(position, historyAdapter.getItemCount());
}
presenter.deleteHistory(new ArrayList<>(deleteList));
mode.finish();
presenter.deleteHistory(new ArrayList<>(deleteList));
mode.finish();
return Unit.INSTANCE;
});
return true;
}
return false;
@ -159,7 +168,8 @@ public class HistoryActivity extends BaseActivity implements HistoryContract.Vie
private void setupHistoryAdapter() {
historyAdapter = new HistoryAdapter(historyList, deleteList, this);
historyAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override public void onChanged() {
@Override
public void onChanged() {
super.onChanged();
noHistory.setVisibility(historyList.size() == 0 ? View.VISIBLE : View.GONE);
}
@ -226,12 +236,17 @@ public class HistoryActivity extends BaseActivity implements HistoryContract.Vie
onBackPressed();
return true;
} else if (itemId == R.id.menu_history_clear) {
presenter.deleteHistory(new ArrayList<>(fullHistory));
fullHistory.clear();
historyList.clear();
historyAdapter.notifyDataSetChanged();
setResult(RESULT_OK, new Intent().putExtra(USER_CLEARED_HISTORY, true));
Toast.makeText(this, R.string.all_history_cleared_toast, Toast.LENGTH_SHORT).show();
if (fullHistory.size() > 0) {
dialogShower.show(KiwixDialog.DeleteHistory.INSTANCE, (Function0<Unit>) () -> {
presenter.deleteHistory(new ArrayList<>(fullHistory));
fullHistory.clear();
historyList.clear();
historyAdapter.notifyDataSetChanged();
setResult(RESULT_OK, new Intent().putExtra(USER_CLEARED_HISTORY, true));
Toast.makeText(this, R.string.all_history_cleared_toast, Toast.LENGTH_SHORT).show();
return Unit.INSTANCE;
});
}
return true;
}
return super.onOptionsItemSelected(item);
@ -298,7 +313,8 @@ public class HistoryActivity extends BaseActivity implements HistoryContract.Vie
}
}
@Override protected void injection(CoreComponent coreComponent) {
coreComponent.inject(this);
@Override
protected void injection(CoreComponent coreComponent) {
coreComponent.activityComponentBuilder().activity(this).build().inject(this);
}
}

View File

@ -18,6 +18,7 @@
package org.kiwix.kiwixmobile.core.main;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.text.Editable;
@ -53,7 +54,7 @@ public class CompatFindActionModeCallback
private ActionMode actionMode;
CompatFindActionModeCallback(Context context) {
@SuppressLint("InflateParams") CompatFindActionModeCallback(Context context) {
customView = LayoutInflater.from(context).inflate(R.layout.webview_search, null);
editText = customView.findViewById(R.id.edit);
editText.setOnClickListener(this);
@ -96,22 +97,18 @@ public class CompatFindActionModeCallback
"WebView supplied to CompatFindActionModeCallback cannot be null");
}
this.webView = webView;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
findResultsTextView.setVisibility(View.VISIBLE);
this.webView.setFindListener((activeMatchOrdinal, numberOfMatches, isDoneCounting) -> {
String result;
if (editText.getText().toString().isEmpty()) {
result = "";
} else if (numberOfMatches == 0) {
result = "0/0";
} else {
result = (activeMatchOrdinal + 1) + "/" + numberOfMatches;
}
findResultsTextView.setText(result);
});
} else {
findResultsTextView.setVisibility(View.GONE);
}
findResultsTextView.setVisibility(View.VISIBLE);
this.webView.setFindListener((activeMatchOrdinal, numberOfMatches, isDoneCounting) -> {
String result;
if (editText.getText().toString().isEmpty()) {
result = "";
} else if (numberOfMatches == 0) {
result = "0/0";
} else {
result = (activeMatchOrdinal + 1) + "/" + numberOfMatches;
}
findResultsTextView.setText(result);
});
}
// Move the highlight to the next match.
@ -134,17 +131,9 @@ public class CompatFindActionModeCallback
CharSequence find = editText.getText();
if (find == null || find.length() == 0) {
webView.clearMatches();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
webView.findAllAsync("");
} else {
webView.findAll("");
}
webView.findAllAsync("");
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
webView.findAllAsync(find.toString());
} else {
webView.findAll(find.toString());
}
webView.findAllAsync(find.toString());
// Enable word highlighting with reflection
try {

View File

@ -556,10 +556,13 @@ public abstract class CoreMainActivity extends BaseActivity
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
closeAllTabsButton.setImageDrawable(
ContextCompat.getDrawable(this, R.drawable.ic_close_black_24dp));
startAnimation(tabSwitcherRoot, R.anim.slide_up);
tabSwitcherRoot.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
contentFrame.setVisibility(View.VISIBLE);
if (tabSwitcherRoot.getVisibility() == View.VISIBLE) {
tabSwitcherRoot.setVisibility(View.GONE);
startAnimation(tabSwitcherRoot, R.anim.slide_up);
progressBar.setVisibility(View.VISIBLE);
contentFrame.setVisibility(View.VISIBLE);
}
selectTab(currentWebViewIndex);
if (mainMenu != null) {
mainMenu.showWebViewOptions(!urlIsInvalid());
}
@ -849,10 +852,12 @@ public abstract class CoreMainActivity extends BaseActivity
webViewList.remove(index);
tabsAdapter.notifyItemRemoved(index);
tabsAdapter.notifyDataSetChanged();
Snackbar.make(snackbarRoot, R.string.tab_closed, Snackbar.LENGTH_LONG)
Snackbar.make(tabSwitcherRoot, R.string.tab_closed, Snackbar.LENGTH_LONG)
.setAction(R.string.undo, v -> {
webViewList.add(index, tempForUndo);
tabsAdapter.notifyItemInserted(index);
tabsAdapter.notifyDataSetChanged();
Snackbar.make(snackbarRoot,"Tab restored",Snackbar.LENGTH_SHORT).show();
setUpWebViewWithTextToSpeech();
})
.show();
@ -1107,13 +1112,11 @@ public abstract class CoreMainActivity extends BaseActivity
}
private void requestExternalStoragePermission() {
if (Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
ActivityCompat.requestPermissions(
this,
new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
REQUEST_STORAGE_PERMISSION
);
}
ActivityCompat.requestPermissions(
this,
new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
REQUEST_STORAGE_PERMISSION
);
}
private void openAndSetInContainer(File file) {

View File

@ -108,9 +108,7 @@ public class KiwixTextToSpeech {
currentTTSTask = null;
} else if (tts.isSpeaking()) {
if (tts.stop() == TextToSpeech.SUCCESS) {
if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
tts.setOnUtteranceProgressListener(null);
}
tts.setOnUtteranceProgressListener(null);
onSpeakingListener.onSpeakingEnded();
}
} else {
@ -172,9 +170,7 @@ public class KiwixTextToSpeech {
public void stop() {
if (tts.stop() == TextToSpeech.SUCCESS) {
currentTTSTask = null;
if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
tts.setOnUtteranceProgressListener(null);
}
tts.setOnUtteranceProgressListener(null);
onSpeakingListener.onSpeakingEnded();
}
}
@ -260,9 +256,7 @@ public class KiwixTextToSpeech {
void pause() {
paused = true;
currentPiece.decrementAndGet();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
tts.setOnUtteranceProgressListener(null);
}
tts.setOnUtteranceProgressListener(null);
tts.stop();
}
@ -285,33 +279,31 @@ public class KiwixTextToSpeech {
stop();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String s) {
tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String s) {
}
@Override
public void onDone(String s) {
int line = currentPiece.intValue();
if (line >= pieces.size() && !paused) {
stop();
return;
}
@Override
public void onDone(String s) {
int line = currentPiece.intValue();
tts.speak(pieces.get(line), TextToSpeech.QUEUE_ADD, params);
currentPiece.getAndIncrement();
}
if (line >= pieces.size() && !paused) {
stop();
return;
}
tts.speak(pieces.get(line), TextToSpeech.QUEUE_ADD, params);
currentPiece.getAndIncrement();
}
@Override
public void onError(String s) {
Log.e(TAG_KIWIX, "TextToSpeech Error: " + s);
//TODO: Surface to user
}
});
}
@Override
public void onError(String s) {
Log.e(TAG_KIWIX, "TextToSpeech Error: " + s);
//TODO: Surface to user
}
});
}
void stop() {

View File

@ -84,9 +84,7 @@ public class KiwixWebView extends VideoEnabledWebView {
settings.setDomStorageEnabled(true);
settings.setJavaScriptEnabled(true);
clearCache(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
settings.setAllowUniversalAccessFromFileURLs(true);
}
settings.setAllowUniversalAccessFromFileURLs(true);
setWebViewClient(webViewClient);
final KiwixWebChromeClient client =
new KiwixWebChromeClient(callback, nonVideoView, videoView, this);
@ -191,7 +189,7 @@ public class KiwixWebView extends VideoEnabledWebView {
return fileName.substring(fileName.indexOf("%3A") + 1);
}
@Override
@SuppressLint("StringFormatInvalid") @Override
public void handleMessage(Message msg) {
String url = (String) msg.getData().get("url");
String src = (String) msg.getData().get("src");

View File

@ -243,7 +243,7 @@ public abstract class CorePrefsFragment extends PreferenceFragment implements
@SuppressLint("SetJavaScriptEnabled")
public void openCredits() {
WebView view =
@SuppressLint("InflateParams") WebView view =
(WebView) LayoutInflater.from(getActivity()).inflate(R.layout.credits_webview, null);
view.loadUrl("file:///android_asset/credits.html");
if (nightModeConfig.isNightModeActive()) {

View File

@ -147,10 +147,11 @@ sealed class KiwixDialog(
)
object ClearAllNotes : KiwixDialog(
null,
R.string.delete_notes_confirmation_msg,
R.string.yes,
android.R.string.cancel
message = null,
positiveMessage = R.string.yes,
negativeMessage = R.string.no,
icon = R.drawable.ic_warning
)
data class OpenCredits(val customGetView: (() -> View)?) : KiwixDialog(
@ -184,6 +185,20 @@ sealed class KiwixDialog(
R.string.open_in_new_tab, R.string.open_in_new_tab
)
}
object DeleteHistory : KiwixDialog(
null,
R.string.delete_history,
R.string.yes,
R.string.no
)
object DeleteBookmarks : KiwixDialog(
null,
R.string.delete_bookmarks,
R.string.yes,
R.string.no
)
}
interface HasBodyFormatArgs {

View File

@ -102,7 +102,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginLeft="100dp"
android:layout_marginTop="8dp"
android:checked="true"
android:text="@string/crash_checkbox_language"
@ -116,7 +115,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginLeft="100dp"
android:layout_marginTop="8dp"
android:checked="true"
android:text="@string/crash_checkbox_logs"
@ -130,7 +128,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginLeft="100dp"
android:layout_marginTop="8dp"
android:checked="true"
android:text="@string/crash_checkbox_exception"
@ -144,7 +141,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginLeft="100dp"
android:layout_marginTop="8dp"
android:checked="true"
android:text="@string/crash_checkbox_zimfiles"
@ -158,7 +154,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginLeft="100dp"
android:layout_marginTop="8dp"
android:checked="true"
android:text="@string/crash_checkbox_device"

View File

@ -44,7 +44,7 @@
android:layout_margin="@dimen/activity_horizontal_margin"
android:text="@string/download_books"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

View File

@ -15,9 +15,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_toEndOf="@id/file_name"
android:layout_toRightOf="@id/file_name"
android:gravity="end"
android:padding="10dp"
android:textSize="18sp" />

View File

@ -11,8 +11,8 @@
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_bar">
<LinearLayout
@ -27,17 +27,17 @@
android:background="@android:color/transparent"
android:hint="@string/wiki_article_title"
android:maxLines="1"
android:paddingLeft="20dp"
android:paddingStart="20dp"
android:paddingTop="10dp"
android:paddingRight="20dp"
android:paddingEnd="20dp"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
android:layout_marginBottom="5dp"
android:background="#000000" />
@ -46,13 +46,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:gravity="top|left"
android:gravity="top|start"
android:hint="@string/note"
android:inputType="textMultiLine|textCapSentences|textAutoCorrect"
android:minLines="6"
android:paddingLeft="20dp"
android:paddingStart="20dp"
android:paddingTop="5dp"
android:paddingRight="20dp"
android:paddingEnd="20dp"
android:paddingBottom="10dp"
android:scrollbars="vertical"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" />

View File

@ -26,7 +26,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="10dp"
android:paddingRight="10dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/horizontal_padding"
@ -92,7 +91,6 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/item_book_title"
app:layout_constraintTop_toBottomOf="@id/item_book_date"
@ -120,8 +118,8 @@
android:layout_height="0dp"
android:background="?android:attr/selectableItemBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -26,7 +26,6 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:alpha="0.87"
android:paddingTop="8dp"
android:paddingBottom="8dp"

View File

@ -3,8 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/kiwix_search_widget_layout_id_height"
android:layout_marginLeft="@dimen/kiwix_search_widget_margin"
android:layout_marginRight="@dimen/kiwix_search_widget_margin"
android:layout_marginStart="@dimen/kiwix_search_widget_margin"
android:layout_marginEnd="@dimen/kiwix_search_widget_margin"
android:background="@drawable/search_widget_background"
android:gravity="center_vertical"
android:orientation="horizontal"

View File

@ -13,14 +13,15 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/title_text_margin"
android:layout_marginRight="@dimen/title_text_margin"
android:layout_marginStart="@dimen/title_text_margin"
android:layout_marginEnd="@dimen/title_text_margin"
android:ellipsize="end"
android:fontFamily="sans-serif-light"
android:gravity="center_vertical"
android:maxLines="1"
android:minHeight="?listPreferredItemHeightSmall"
android:paddingLeft="@dimen/title_text_padding"
android:paddingStart="@dimen/title_text_padding"
android:paddingEnd="0dp"
android:textAppearance="?textAppearanceBody1"
tools:text="Some text" />

View File

@ -3,9 +3,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/slider_dialog_horizontal_padding"
android:paddingStart="@dimen/slider_dialog_horizontal_padding"
android:paddingTop="@dimen/dimen_medium_padding"
android:paddingRight="@dimen/slider_dialog_horizontal_padding"
android:paddingEnd="@dimen/slider_dialog_horizontal_padding"
android:paddingBottom="@dimen/dimen_medium_padding">
<TextView

View File

@ -23,7 +23,7 @@
android:id="@+id/edit"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/webview_search_edit_text_margin_right"
android:layout_marginEnd="@dimen/webview_search_edit_text_margin_right"
android:layout_weight="1"
android:focusableInTouchMode="true"
android:hint="@string/search_label"
@ -41,7 +41,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:gravity="center"
android:textColor="@android:color/darker_gray"
tools:text="2/10" />

View File

@ -37,7 +37,7 @@
<string name="no_books_selected_toast_message">يُرجى اختيار الكتب أولًا</string>
<string name="server_failed_message">لا يمكن بدء الخادم. يُرجى تشغيل الهوت-سبوت الخاص بك</string>
<string name="server_failed_toast_message">لا يمكن بدء الخادم.</string>
<string name="server_started__successfully_toast_message">بدأ الخادم بنجاح.</string>
<string name="server_started_successfully_toast_message">بدأ الخادم بنجاح.</string>
<string name="hotspot_turned_on">الهوت-سبوت قيد التشغيل</string>
<string name="hotspot_details_message">فيما يلي تفاصيل الهوت-سبوت الخاص بك.\nSSID: %1$s \nPass: %2$s</string>
<string name="server_textview_default_message">حدد الملفات التي ترغب في استضافتها على الخادم</string>
@ -145,7 +145,7 @@
<string name="next">التالي</string>
<string name="previous">السابق</string>
<string name="wifi_only_title">السماح بتنزيل المحتوى عبر شبكة المحمول؟</string>
<string name="wifi_only_msg">إذا اخترت \"نعم\"، فلن يتم تحذيرك في المستقبل. مع ذلك، يمكنك دائمًا تغيير هذا في الإعدادات.</string>
<string name="wifi_only_msg">إذا اخترت \“نعم\”، فلن يتم تحذيرك في المستقبل. مع ذلك، يمكنك دائمًا تغيير هذا في الإعدادات.</string>
<string name="pref_wifi_only">تنزيل المحتوى عبر واي فاي فقط</string>
<string name="time_day">يوم</string>
<string name="time_hour">ساعة</string>

View File

@ -37,7 +37,7 @@
<string name="no_books_selected_toast_message">Vyberte nejprve knihy</string>
<string name="server_failed_message">Nemohu spustit server. Zapněte prosím svůj hotspot</string>
<string name="server_failed_toast_message">Nelze spustit server.</string>
<string name="server_started__successfully_toast_message">Server úspěšně spuštěn.</string>
<string name="server_started_successfully_toast_message">Server úspěšně spuštěn.</string>
<string name="hotspot_turned_on">Hotspot spuštěn</string>
<string name="hotspot_details_message">Následují podrobnosti vašeho hotspotu.\nSSID : %1$s \nPass : %2$s</string>
<string name="server_textview_default_message">Vyberte soubory, které si přejete hostovat na svém serveru</string>

View File

@ -31,7 +31,7 @@
<string name="open_in_new_tab">¿Abrir enlace en una nueva pestaña?</string>
<string name="go_to_wifi_settings_label">Ir a config. de wifi</string>
<string name="server_failed_toast_message">No se pudo iniciar el servidor.</string>
<string name="server_started__successfully_toast_message">Se inició el servidor correctamente.</string>
<string name="server_started_successfully_toast_message">Se inició el servidor correctamente.</string>
<string name="progress_dialog_starting_server">Iniciando el servidor</string>
<string name="hotspot_dialog_neutral_button">SÍ, LO HE INICIADO</string>
<string name="start_server_label">Iniciar servidor</string>

View File

@ -41,7 +41,7 @@
<string name="no_books_selected_toast_message">Veuillez dabord choisir les livres</string>
<string name="server_failed_message">Impossible de démarrer le serveur. Veuillez activer votre point daccès WiFi</string>
<string name="server_failed_toast_message">Impossible de démarrer le serveur.</string>
<string name="server_started__successfully_toast_message">Serveur démarré avec succès.</string>
<string name="server_started_successfully_toast_message">Serveur démarré avec succès.</string>
<string name="hotspot_turned_on">Point daccès activé</string>
<string name="hotspot_details_message">Voici les détails de votre point daccès local.\nSSID: %1$s\nPasse: %2$s</string>
<string name="server_textview_default_message">Sélectionnez les fichiers que vous voulez héberger sur le serveur</string>

View File

@ -37,7 +37,7 @@
<string name="no_books_selected_toast_message">נא לבחור ספרים קודם</string>
<string name="server_failed_message">לא היה אפשר להתחיל את השרת. נא להפעיל את נקודת החיבור שלך</string>
<string name="server_failed_toast_message">לא היה אפשר להריץ את השרת.</string>
<string name="server_started__successfully_toast_message">השרת הופעל בהצלחה.</string>
<string name="server_started_successfully_toast_message">השרת הופעל בהצלחה.</string>
<string name="hotspot_turned_on">נקודת החיבור הופעלה</string>
<string name="hotspot_details_message">להלן הפרטים של נקודת החיבור המקומית שלך.\nSSID : %1$s \nPass : %2$s</string>
<string name="server_textview_default_message">נא לבחור את הקבצים שברצונך לארח בשרת</string>

View File

@ -38,7 +38,7 @@
<string name="no_books_selected_toast_message">책을 먼저 선택해 주십시오</string>
<string name="server_failed_message">서버를 시작하지 못했습니다. 핫스팟을 켜 주십시오</string>
<string name="server_failed_toast_message">서버를 시작하지 못했습니다.</string>
<string name="server_started__successfully_toast_message">서버가 성공적으로 시작되었습니다.</string>
<string name="server_started_successfully_toast_message">서버가 성공적으로 시작되었습니다.</string>
<string name="hotspot_turned_on">핫스팟이 켜져있습니다</string>
<string name="hotspot_details_message">다음은 로컬 핫스팟의 상세 정보입니다.\nSSID : %1$s \nPass : %2$s</string>
<string name="server_textview_default_message">서버에 호스팅할 파일을 선택하십시오</string>

View File

@ -31,7 +31,7 @@
<string name="no_books_selected_toast_message">Најпрвин одберете книги</string>
<string name="server_failed_message">Не можев да го покренам опслужувачот. Вклучете ја пристапната точка</string>
<string name="server_failed_toast_message">Не можев да го покренам опслужувачот.</string>
<string name="server_started__successfully_toast_message">Опслужувачот е успешно покренат.</string>
<string name="server_started_successfully_toast_message">Опслужувачот е успешно покренат.</string>
<string name="hotspot_turned_on">Пристапната точка е вклучена</string>
<string name="hotspot_details_message">Следат поединости за вашата месна точка на пристап. \nSSID : %1$s \nЛозинка : %2$s</string>
<string name="server_textview_default_message">Изберете ги податотеките што сакате да ги вдомите на опслужувачот</string>

View File

@ -39,7 +39,7 @@
<string name="hotspot_running">Uruchamianie Hotspot</string>
<string name="no_books_selected_toast_message">Proszę wybrać najpierw książki</string>
<string name="server_failed_toast_message">Nie można uruchomić serwera.</string>
<string name="server_started__successfully_toast_message">Serwer został uruchomiony pomyślnie.</string>
<string name="server_started_successfully_toast_message">Serwer został uruchomiony pomyślnie.</string>
<string name="hotspot_turned_on">Hotspot włączony</string>
<string name="hotspot_details_message">Poniżej znajdują się szczegółowe informacje o lokalnym hotspocie.\nSSID : %1$s \nPass : %2$s</string>
<string name="server_textview_default_message">Wybierz pliki, które chcesz hostować na serwerze</string>

View File

@ -37,7 +37,7 @@
<string name="no_books_selected_toast_message">Selecione primeiro os livros</string>
<string name="server_failed_message">Não foi possível iniciar o servidor. Por favor, ligue seu ponto de acesso</string>
<string name="server_failed_toast_message">Não foi possível iniciar o servidor.</string>
<string name="server_started__successfully_toast_message">Servidor iniciado com sucesso.</string>
<string name="server_started_successfully_toast_message">Servidor iniciado com sucesso.</string>
<string name="hotspot_turned_on">Ponto de acesso ativado</string>
<string name="hotspot_details_message">A seguir estão os detalhes do seu ponto de acesso local.\nSSID : %1$s \nPasse : %2$s</string>
<string name="server_textview_default_message">Selecione os arquivos que você deseja hospedar no servidor</string>

View File

@ -32,7 +32,7 @@
<string name="no_books_selected_toast_message">In antis ischerta libros</string>
<string name="server_failed_message">Aviamentu de su servidore fallidu. Pro praghere allughe s\'hotspot tuo</string>
<string name="server_failed_toast_message">Aviamentu de su servidore fallidu.</string>
<string name="server_started__successfully_toast_message">Servidore aviadu chene problemas.</string>
<string name="server_started_successfully_toast_message">Servidore aviadu chene problemas.</string>
<string name="hotspot_turned_on">Hotspot allutu</string>
<string name="hotspot_details_message">Sos chi sighint sunt sos detàllios de s\'hotspot locale tuo. \nSSID : %1$s \nCrae : %2$s</string>
<string name="server_textview_default_message">Ischerta sos documentos chi cheres istrangiare in su servidore</string>

View File

@ -28,7 +28,7 @@
<string name="go_to_wifi_settings_label">Gå till WiFi-inställningar</string>
<string name="no_books_selected_toast_message">Välj böcker först</string>
<string name="server_failed_toast_message">Kunde inte starta server.</string>
<string name="server_started__successfully_toast_message">Servern startades.</string>
<string name="server_started_successfully_toast_message">Servern startades.</string>
<string name="progress_dialog_starting_server">Startar server</string>
<string name="hotspot_dialog_neutral_button">JA, JAG HAR AKTIVERAT DET</string>
<string name="start_server_label">Starta server</string>

View File

@ -42,7 +42,7 @@
<string name="no_books_selected_toast_message">Lütfen önce kitapları seçin</string>
<string name="server_failed_message">Sunucu başlatılamadı. Lütfen etkin noktanızıın</string>
<string name="server_failed_toast_message">Sunucu başlatılamadı.</string>
<string name="server_started__successfully_toast_message">Sunucu başarıyla başladı.</string>
<string name="server_started_successfully_toast_message">Sunucu başarıyla başladı.</string>
<string name="hotspot_turned_on">Hotspot açık</string>
<string name="hotspot_details_message">Aşağıda yerel etkin noktanızın ayrıntıları verilmiştir.\nSSID: %1$s\nGeçiş: %2$s</string>
<string name="server_textview_default_message">Sunucuda barındırmak istediğiniz dosyaları seçin</string>

View File

@ -25,7 +25,7 @@
<string name="go_to_wifi_settings_label">WIFI პარამეტრეფშა გინულა</string>
<string name="server_failed_message">სერვერქ ვაჩქართინესო. ქორთხინთ, ჩართით ინტერნეტი</string>
<string name="server_failed_toast_message">სერვერქ ვეჩირთინუ.</string>
<string name="server_started__successfully_toast_message">ჩერვერქ ჩერთუ.</string>
<string name="server_started_successfully_toast_message">ჩერვერქ ჩერთუ.</string>
<string name="hotspot_details_message">გიმე მოჩამილი რე თქვანი აბანური ინტერნეტ-მეჭირინაფაშ ჭურჭულიშ გეშა ინფორმაცია. \nSSID : %1$s \nPass : %2$s</string>
<string name="hotspot_dialog_title">ჩართით თქვანი WIFI მეჭირინაფაშ ჭურჭული</string>
<string name="hotspot_dialog_neutral_button">ქო, ჩართული მაფუ</string>

View File

@ -36,7 +36,7 @@
<string name="no_books_selected_toast_message">請先選擇書籍</string>
<string name="server_failed_message">無法開啟伺服器,請啟動您的熱點</string>
<string name="server_failed_toast_message">無法開啟伺服器。</string>
<string name="server_started__successfully_toast_message">伺服器開啟成功。</string>
<string name="server_started_successfully_toast_message">伺服器開啟成功。</string>
<string name="hotspot_turned_on">熱點已啟動</string>
<string name="hotspot_details_message">以下為您的本地熱點詳細內容。\nSSID%1$s \n密碼%2$s</string>
<string name="server_textview_default_message">選擇您想要在伺服器上託管的檔案</string>

View File

@ -28,7 +28,8 @@
<string name="no_books_selected_toast_message" tools:keep="@string/no_books_selected_toast_message">Please select books first</string>
<string name="server_failed_message" tools:keep="@string/server_failed_message">Couldnt start server. Please turn on your hotspot</string>
<string name="server_failed_toast_message" tools:keep="@string/server_failed_toast_message">Couldnt start server.</string>
<string name="server_started__successfully_toast_message" tools:keep="@string/server_started__successfully_toast_message">Server started successfully.</string>
<string name="server_started_successfully_toast_message" tools:keep="@string/server_started_successfully_toast_message">Server started successfully.</string>
<string name="server_stopped_successfully_toast_message" tools:keep="@string/server_stopped_successfully_toast_message">Server stopped successfully.</string>
<string name="hotspot_turned_on">Hotspot turned on</string>
<string name="hotspot_details_message">Following are the details of your local hotspot. \nSSID : %1$s \nPass : %2$s</string>
<string name="server_textview_default_message" tools:keep="@string/server_textview_default_message">Select the files you wish to host on the server</string>
@ -259,6 +260,8 @@
<string name="no_bookmarks">No Bookmarks</string>
<string name="no_history">No History</string>
<string name="device_default">Device Default</string>
<string name="delete_history">Delete History?</string>
<string name="delete_bookmarks">Delete Bookmarks?</string>
<string-array name="pref_night_modes_entries">
<item>On</item>
<item>Off</item>

View File

@ -1,5 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<issues format="5" by="lint 3.5.2" client="gradle" variant="customexampleDebug" version="3.5.2">
<issues format="5" by="lint 3.5.3" client="gradle" variant="customexampleDebug" version="3.5.3">
<issue
id="MissingTranslation"
message="&quot;retry&quot; is not translated in &quot;ml&quot; (Malayalam), &quot;qq&quot;, &quot;cs&quot; (Czech), &quot;tg&quot; (Tajik)"
errorLine1=" &lt;string name=&quot;retry&quot;>Retry&lt;/string>"
errorLine2=" ~~~~~~~~~~~~">
<location
file="src/main/res/values/strings.xml"
line="4"
column="11"/>
</issue>
<issue
id="MissingTranslation"
message="&quot;download&quot; is not translated in &quot;zgh&quot; (Standard Moroccan Tamazight), &quot;et&quot; (Estonian), &quot;cs&quot; (Czech), &quot;da&quot; (Danish)"
errorLine1=" &lt;string name=&quot;download&quot;>Download&lt;/string>"
errorLine2=" ~~~~~~~~~~~~~~~">
<location
file="src/main/res/values/strings.xml"
line="5"
column="11"/>
</issue>
<issue
id="MissingTranslation"
message="&quot;invalid_installation&quot; is not translated in &quot;fi&quot; (Finnish), &quot;zgh&quot; (Standard Moroccan Tamazight), &quot;skr&quot;, &quot;ml&quot; (Malayalam), &quot;qq&quot;, &quot;sv&quot; (Swedish), &quot;it&quot; (Italian), &quot;es&quot; (Spanish), &quot;et&quot; (Estonian), &quot;cs&quot; (Czech), &quot;tg&quot; (Tajik), &quot;lb&quot; (Luxembourgish), &quot;da&quot; (Danish)"
errorLine1=" &lt;string name=&quot;invalid_installation&quot;>Invalid Install. Please Download Zim.\n Ensure WiFi is on and you have enough storage&lt;/string>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/res/values/strings.xml"
line="6"
column="11"/>
</issue>
<issue
id="UnpackedNativeCode"
@ -7,7 +40,7 @@
errorLine1=" &lt;application"
errorLine2=" ^">
<location
file="src\main\AndroidManifest.xml"
file="src/main/AndroidManifest.xml"
line="6"
column="3"/>
</issue>
@ -18,7 +51,7 @@
errorLine1=" &lt;TextView"
errorLine2=" ~~~~~~~~">
<location
file="src\main\res\layout\layout_custom_download_error.xml"
file="src/main/res/layout/layout_custom_download_error.xml"
line="10"
column="4"/>
</issue>
@ -29,7 +62,7 @@
errorLine1=" &lt;TextView"
errorLine2=" ~~~~~~~~">
<location
file="src\main\res\layout\layout_custom_download_in_progress.xml"
file="src/main/res/layout/layout_custom_download_in_progress.xml"
line="8"
column="4"/>
</issue>
@ -40,7 +73,7 @@
errorLine1=" &lt;TextView"
errorLine2=" ~~~~~~~~">
<location
file="src\main\res\layout\layout_custom_download_in_progress.xml"
file="src/main/res/layout/layout_custom_download_in_progress.xml"
line="28"
column="4"/>
</issue>
@ -51,7 +84,7 @@
errorLine1="class CustomMainActivity : CoreMainActivity() {"
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="src\main\java\org\kiwix\kiwixmobile\custom\main\CustomMainActivity.kt"
file="src/main/java/org/kiwix/kiwixmobile/custom/main/CustomMainActivity.kt"
line="55"
column="7"/>
</issue>
@ -62,7 +95,7 @@
errorLine1=" &lt;ImageView"
errorLine2=" ~~~~~~~~~">
<location
file="src\main\res\layout\activity_custom_download.xml"
file="src/main/res/layout/activity_custom_download.xml"
line="9"
column="4"/>
</issue>

View File

@ -6,7 +6,8 @@
<application
android:name=".CustomApp"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round">
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<activity
android:name=".splash.CustomSplashActivity"
android:label="@string/app_name"

View File

@ -12,8 +12,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:src="@mipmap/ic_launcher_foreground"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ViewAnimator
@ -23,8 +23,8 @@
android:inAnimation="@android:anim/fade_in"
android:outAnimation="@android:anim/fade_out"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cd_icon">
<include layout="@layout/layout_custom_download_required" />

View File

@ -13,8 +13,8 @@
android:gravity="center"
android:text="@string/complete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".3" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -13,8 +13,8 @@
android:layout_height="wrap_content"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".3" />
@ -24,7 +24,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/retry"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cd_error_text" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -10,8 +10,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/cd_progress"
app:layout_constraintLeft_toLeftOf="@+id/cd_progress"
app:layout_constraintRight_toRightOf="@+id/cd_progress" />
app:layout_constraintStart_toStartOf="@+id/cd_progress"
app:layout_constraintEnd_toEndOf="@+id/cd_progress" />
<ProgressBar
android:id="@+id/cd_progress"
@ -20,8 +20,8 @@
android:layout_height="wrap_content"
android:max="100"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".3" />
@ -30,7 +30,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
app:layout_constraintBottom_toBottomOf="@id/cd_progress"
app:layout_constraintStart_toEndOf="@id/cd_progress"
app:layout_constraintTop_toTopOf="@id/cd_progress" />

View File

@ -13,8 +13,8 @@
android:gravity="center"
android:text="@string/invalid_installation"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".3" />
@ -24,8 +24,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/download"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cd_text" />
</androidx.constraintlayout.widget.ConstraintLayout>