Merge pull request #2553 from kiwix/release/3.4.3

Release/3.4.3
This commit is contained in:
Abdul Wadood 2020-12-15 20:34:11 +05:30 committed by GitHub
commit 97b51a1c49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 283 additions and 144 deletions

View File

@ -1,3 +1,11 @@
3.4.3
NEW: Updated translations
BUGFIX: Video seek was not working
BUGFIX: Back button in history and bookmarks toolbar always took to library
BUGFIX: Books hosted from android client were not updating on browser dynamically
BUGFIX: Creating multiple tabs was causing `loading` in previously opened tabs
BUGFIX: Messages displayed when no books are present were inconsistent typographically
3.4.2
NEW: Service worker support for war2c zim files
NEW: Updated translations

View File

@ -11,7 +11,7 @@ apply(from = rootProject.file("jacoco.gradle"))
ext {
set("versionMajor", 3)
set("versionMinor", 4)
set("versionPatch", 2)
set("versionPatch", 3)
}
fun generateVersionName() = "${ext["versionMajor"]}.${ext["versionMinor"]}.${ext["versionPatch"]}"

View File

@ -24,9 +24,12 @@ Abdul Wadood<br>
Adeel Zafar<br>
Aditya Sood<br>
Ayoub Dardory<br>
Ayush Shrivastava<br>
Christian Pühringer<br>
Elad Keyshawn<br>
Emmanuel Engelhart<br>
Frans-Lukas Lövenvald<br>
Gourishankar Panda<br>
Isaac Hutt<br>
Joseph E. Reeve<br>
Julian Harty<br>

View File

@ -23,9 +23,8 @@ import android.app.Service
import android.content.Context
import dagger.Module
import dagger.Provides
import org.kiwix.kiwixlib.JNIKiwixServer
import org.kiwix.kiwixlib.Library
import org.kiwix.kiwixmobile.di.ServiceScope
import org.kiwix.kiwixmobile.webserver.KiwixServer
import org.kiwix.kiwixmobile.webserver.WebServerHelper
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotNotificationManager
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.HotspotStateReceiver
@ -38,25 +37,15 @@ class ServiceModule {
@Provides
@ServiceScope
fun providesWebServerHelper(
jniKiwixLibrary: Library,
kiwixServer: JNIKiwixServer,
kiwixServerFactory: KiwixServer.Factory,
ipAddressCallbacks: IpAddressCallbacks
): WebServerHelper = WebServerHelper(jniKiwixLibrary, kiwixServer, ipAddressCallbacks)
): WebServerHelper = WebServerHelper(kiwixServerFactory, ipAddressCallbacks)
@Provides
@ServiceScope
fun providesIpAddressCallbacks(service: Service): IpAddressCallbacks =
service as IpAddressCallbacks
@Provides
@ServiceScope
fun providesLibrary(): Library = Library()
@Provides
@ServiceScope
fun providesJNIKiwixServer(jniKiwixLibrary: Library): JNIKiwixServer =
JNIKiwixServer(jniKiwixLibrary)
@Provides
@ServiceScope
fun providesHotspotNotificationManager(

View File

@ -23,8 +23,8 @@ import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.navigation.fragment.findNavController
import androidx.viewpager.widget.ViewPager
import kotlinx.android.synthetic.main.fragment_intro.get_started
import kotlinx.android.synthetic.main.fragment_intro.tab_indicator
@ -35,7 +35,6 @@ import org.kiwix.kiwixmobile.cachedComponent
import org.kiwix.kiwixmobile.core.base.BaseActivity
import org.kiwix.kiwixmobile.core.base.BaseFragment
import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.zim_manager.SimplePageChangeListener
import java.util.Timer
import java.util.TimerTask
@ -103,15 +102,10 @@ class IntroFragment : BaseFragment(), IntroContract.View, FragmentActivityExtens
views = emptyArray()
}
override fun onBackPressed(activity: AppCompatActivity): FragmentActivityExtensions.Super {
activity.finish()
return super.onBackPressed(activity)
}
private fun navigateToLibrary() {
dismissAutoRotate()
presenter.setIntroShown()
(requireActivity() as KiwixMainActivity).navController.popBackStack()
findNavController().navigate(IntroFragmentDirections.actionIntrofragmentToLibraryFragment())
}
private fun updateView(position: Int) {

View File

@ -38,6 +38,7 @@ import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions
import org.kiwix.kiwixmobile.core.di.components.CoreComponent
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
import org.kiwix.kiwixmobile.kiwixActivityComponent
import org.kiwix.kiwixmobile.nav.destination.library.LocalLibraryFragmentDirections
const val NAVIGATE_TO_ZIM_HOST_FRAGMENT = "navigate_to_zim_host_fragment"
@ -94,7 +95,7 @@ class KiwixMainActivity : CoreMainActivity() {
}
}
if (sharedPreferenceUtil.showIntro()) {
navigate(R.id.introFragment)
navigate(LocalLibraryFragmentDirections.actionLibraryFragmentToIntrofragment())
}
}

View File

@ -251,7 +251,9 @@ class KiwixReaderFragment : CoreReaderFragment() {
val zimFile = settings.getString(TAG_CURRENT_FILE, null)
if (zimFile != null) {
openZimFile(File(zimFile))
if (zimReaderContainer.zimFile == null) {
openZimFile(File(zimFile))
}
} else {
getCurrentWebView().snack(R.string.zim_not_opened)
}

View File

@ -0,0 +1,51 @@
/*
* 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/>.
*
*/
package org.kiwix.kiwixmobile.webserver
import android.util.Log
import org.kiwix.kiwixlib.JNIKiwixException
import org.kiwix.kiwixlib.JNIKiwixServer
import org.kiwix.kiwixlib.Library
import javax.inject.Inject
private const val TAG = "KiwixServer"
class KiwixServer @Inject constructor(private val jniKiwixServer: JNIKiwixServer) {
class Factory @Inject constructor() {
fun createKiwixServer(selectedBooksPath: ArrayList<String>): KiwixServer {
val kiwixLibrary = Library()
selectedBooksPath.forEach { path ->
try {
kiwixLibrary.addBook(path)
} catch (e: JNIKiwixException) {
Log.v(TAG, "Couldn't add book with path:{ $path }")
}
}
return KiwixServer(JNIKiwixServer(kiwixLibrary))
}
}
fun startServer(port: Int): Boolean {
jniKiwixServer.setPort(port)
return jniKiwixServer.start()
}
fun stopServer() = jniKiwixServer.stop()
}

View File

@ -25,9 +25,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import org.kiwix.kiwixlib.JNIKiwixException;
import org.kiwix.kiwixlib.JNIKiwixServer;
import org.kiwix.kiwixlib.Library;
import org.kiwix.kiwixmobile.core.utils.ServerUtils;
import org.kiwix.kiwixmobile.webserver.wifi_hotspot.IpAddressCallbacks;
@ -41,15 +39,14 @@ import static org.kiwix.kiwixmobile.core.utils.ServerUtils.INVALID_IP;
public class WebServerHelper {
private static final String TAG = "WebServerHelper";
private Library kiwixLibrary;
private JNIKiwixServer kiwixServer;
private KiwixServer kiwixServer;
private KiwixServer.Factory kiwixServerFactory;
private IpAddressCallbacks ipAddressCallbacks;
private boolean isServerStarted;
@Inject public WebServerHelper(@NonNull Library kiwixLibrary,
@NonNull JNIKiwixServer kiwixServer, @NonNull IpAddressCallbacks ipAddressCallbacks) {
this.kiwixLibrary = kiwixLibrary;
this.kiwixServer = kiwixServer;
@Inject public WebServerHelper(@NonNull KiwixServer.Factory kiwixServerFactory,
@NonNull IpAddressCallbacks ipAddressCallbacks) {
this.kiwixServerFactory = kiwixServerFactory;
this.ipAddressCallbacks = ipAddressCallbacks;
}
@ -65,7 +62,7 @@ public class WebServerHelper {
public void stopAndroidWebServer() {
if (isServerStarted) {
kiwixServer.stop();
kiwixServer.stopServer();
updateServerState(false);
}
}
@ -74,17 +71,9 @@ public class WebServerHelper {
if (!isServerStarted) {
int DEFAULT_PORT = 8080;
ServerUtils.port = DEFAULT_PORT;
for (String path : selectedBooksPath) {
try {
boolean isBookAdded = kiwixLibrary.addBook(path);
Log.v(TAG, "isBookAdded: " + isBookAdded + path);
} catch (JNIKiwixException e) {
Log.v(TAG, "Couldn't add book " + path);
}
}
kiwixServer.setPort(ServerUtils.port);
updateServerState(kiwixServer.start());
Log.v(TAG, "Server status" + isServerStarted);
kiwixServer = kiwixServerFactory.createKiwixServer(selectedBooksPath);
updateServerState(kiwixServer.startServer(ServerUtils.port));
Log.d(TAG, "Server status" + isServerStarted);
}
return isServerStarted;
}

View File

@ -18,9 +18,9 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
android:layout_height="match_parent">
<org.kiwix.kiwixmobile.core.utils.NestedCoordinatorLayout
android:layout_width="match_parent"
@ -44,11 +44,11 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
tools:listitem="@layout/item_download"
android:id="@+id/libraryList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:listitem="@layout/item_download" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</org.kiwix.kiwixmobile.core.utils.NestedCoordinatorLayout>
@ -56,11 +56,12 @@
<TextView
android:id="@+id/libraryErrorText"
style="@style/no_list_content_text"
style="@style/no_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.45" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -19,9 +19,10 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
android:fitsSystemWindows="true">
<org.kiwix.kiwixmobile.core.utils.NestedCoordinatorLayout
android:layout_width="match_parent"
@ -46,33 +47,34 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
tools:listitem="@layout/item_book"
android:id="@+id/zimfilelist"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
tools:listitem="@layout/item_book" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</org.kiwix.kiwixmobile.core.utils.NestedCoordinatorLayout>
<TextView
android:id="@+id/file_management_no_files"
style="@style/no_list_content_text"
android:layout_gravity="center"
style="@style/no_content"
android:text="@string/no_files_here"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.45" />
<Button
android:id="@+id/go_to_downloads_button_no_files"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/download_books"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="@+id/file_management_no_files"
app:layout_constraintStart_toStartOf="@+id/file_management_no_files"
app:layout_constraintTop_toBottomOf="@+id/file_management_no_files" />

View File

@ -69,6 +69,11 @@
<action
android:id="@+id/action_libraryFragment_to_localFileTransferFragment"
app:destination="@id/localFileTransferFragment" />
<action
android:id="@+id/action_libraryFragment_to_introfragment"
app:destination="@id/introFragment"
app:popUpTo="@id/libraryFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
@ -85,7 +90,13 @@
android:id="@+id/introFragment"
android:name="org.kiwix.kiwixmobile.intro.IntroFragment"
android:label="IntroFragment"
tools:layout="@layout/fragment_intro" />
tools:layout="@layout/fragment_intro">
<action
android:id="@+id/action_introfragment_to_libraryFragment"
app:destination="@id/libraryFragment"
app:popUpTo="@id/introFragment"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="@+id/historyFragment"
android:name="org.kiwix.kiwixmobile.core.page.history.HistoryFragment"

View File

@ -25,5 +25,6 @@
<dimen name="favicon_margin_right">8dp</dimen>
<dimen name="item_library_margin_top">8dp</dimen>
<dimen name="stop_horizontal_margin">8dp</dimen>
<dimen name="material_design_appbar_size">48dp</dimen>
</resources>

View File

@ -18,14 +18,4 @@
<resources>
<style name="no_list_content_text" parent="TextAppearance.KiwixTheme.Headline6">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:visibility">gone</item>
<item name="layout_constraintLeft_toLeftOf">parent</item>
<item name="layout_constraintRight_toRightOf">parent</item>
<item name="layout_constraintVertical_bias">0.4</item>
<item name="layout_constraintTop_toTopOf">parent</item>
<item name="layout_constraintBottom_toBottomOf">parent</item>
</style>
</resources>

View File

@ -32,7 +32,7 @@ class ServiceWorkerInitialiser @Inject constructor(zimReaderContainer: ZimReader
ServiceWorkerControllerCompat.getInstance()
.setServiceWorkerClient(object : ServiceWorkerClientCompat() {
override fun shouldInterceptRequest(request: WebResourceRequest): WebResourceResponse? =
zimReaderContainer.load(request.url.toString())
zimReaderContainer.load(request.url.toString(), request.requestHeaders)
})
}
}

View File

@ -778,7 +778,7 @@ public abstract class CoreReaderFragment extends BaseFragment
private KiwixWebView newTab(String url, boolean selectTab) {
KiwixWebView webView = initalizeWebView(url);
webViewList.add(webView);
if(selectTab) {
if (selectTab) {
selectTab(webViewList.size() - 1);
}
tabsAdapter.notifyDataSetChanged();
@ -964,7 +964,6 @@ public abstract class CoreReaderFragment extends BaseFragment
@SuppressWarnings("SameReturnValue")
@OnLongClick(R2.id.bottom_toolbar_bookmark)
boolean goToBookmarks() {
saveTabStates();
CoreMainActivity parentActivity = (CoreMainActivity) requireActivity();
parentActivity.navigate(parentActivity.getBookmarksFragmentResId());
return true;
@ -1205,7 +1204,6 @@ public abstract class CoreReaderFragment extends BaseFragment
}
private void goToSearch(boolean isVoice) {
saveTabStates();
openSearch("", false, isVoice);
}
@ -1235,7 +1233,6 @@ public abstract class CoreReaderFragment extends BaseFragment
break;
case Intent.ACTION_VIEW:
if (intent.getType() == null || !intent.getType().equals("application/octet-stream")) {
saveTabStates();
String searchString =
intent.getData() == null ? "" : intent.getData().getLastPathSegment();
openSearch(searchString, false, false);
@ -1249,7 +1246,6 @@ public abstract class CoreReaderFragment extends BaseFragment
}
private void goToSearchWithText(Intent intent) {
saveTabStates();
String searchString = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
? intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT)
: "";
@ -1570,21 +1566,14 @@ public abstract class CoreReaderFragment extends BaseFragment
try {
JSONArray urls = new JSONArray(zimArticles);
JSONArray positions = new JSONArray(zimPositions);
int i = 0;
// tabs are already restored if the webViewList includes more tabs than the default
if (webViewList.size() == 1) {
getCurrentWebView().setScrollY(positions.getInt(0));
i++;
while (i < urls.length()) {
newTab(UpdateUtils.reformatProviderUrl(urls.getString(i)));
safelyGetWebView(i).setScrollY(positions.getInt(i));
i++;
}
webViewList.clear();
currentWebViewIndex=0;
tabsAdapter.notifyItemRemoved(0);
tabsAdapter.notifyDataSetChanged();
for (int i = 0; i < urls.length(); i++) {
newTab(UpdateUtils.reformatProviderUrl(urls.getString(i)), i == currentTab)
.setScrollY(positions.getInt(i));
}
selectTab(currentTab);
safelyGetWebView(currentTab)
.loadUrl(UpdateUtils.reformatProviderUrl(urls.getString(currentTab)));
getCurrentWebView().setScrollY(positions.getInt(currentTab));
} catch (JSONException e) {
Log.w(TAG_KIWIX, "Kiwix shared preferences corrupted", e);
ContextExtensionsKt.toast(getActivity(), "Could not restore tabs.", Toast.LENGTH_LONG);

View File

@ -139,13 +139,10 @@ public class CoreWebViewClient extends WebViewClient {
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(
WebView view,
WebResourceRequest request)
{
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
String url = convertLegacyUrl(request.getUrl().toString());
if (url.startsWith(CONTENT_PREFIX)) {
return zimReaderContainer.load(url);
return zimReaderContainer.load(url, request.getRequestHeaders());
} else {
return super.shouldInterceptRequest(view, request);
}

View File

@ -172,7 +172,7 @@ open class KiwixWebView @SuppressLint("SetJavaScriptEnabled") constructor(
}.first { !it.exists() }
val source = Uri.parse(src)
try {
zimReaderContainer.load("$source").data.use { inputStream ->
zimReaderContainer.load("$source", emptyMap()).data.use { inputStream ->
fileToSave.outputStream().use { inputStream.copyTo(it) }
}
instance.toast(instance.getString(R.string.save_media_saved, fileToSave.name))

View File

@ -121,6 +121,7 @@ abstract class PageFragment : OnItemClickListener, BaseFragment(), FragmentActiv
recycler_view.layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
recycler_view.adapter = pageAdapter
activity.setSupportActionBar(toolbar)
toolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
activity.supportActionBar?.apply {
setDisplayHomeAsUpEnabled(true)
title = screenTitle

View File

@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.core.reader
import android.webkit.WebResourceResponse
import org.kiwix.kiwixmobile.core.reader.ZimFileReader.Factory
import java.io.File
import java.net.HttpURLConnection
import javax.inject.Inject
import javax.inject.Singleton
@ -45,12 +46,26 @@ class ZimReaderContainer @Inject constructor(private val zimFileReaderFactory: F
fun getRandomArticleUrl() = zimFileReader?.getRandomArticleUrl()
fun isRedirect(url: String): Boolean = zimFileReader?.isRedirect(url) == true
fun getRedirect(url: String): String = zimFileReader?.getRedirect(url) ?: ""
fun load(url: String) =
WebResourceResponse(
zimFileReader?.readMimeType(url),
Charsets.UTF_8.name(),
zimFileReader?.load(url)
)
fun load(url: String, requestHeaders: Map<String, String>): WebResourceResponse {
val data = zimFileReader?.load(url)
return WebResourceResponse(zimFileReader?.readMimeType(url), Charsets.UTF_8.name(), data)
.apply {
val headers = mutableMapOf("Accept-Ranges" to "bytes")
if ("Range" in requestHeaders.keys) {
setStatusCodeAndReasonPhrase(HttpURLConnection.HTTP_PARTIAL, "Partial Content")
val fullSize = data?.available()?.toLong() ?: 0L
val lastByte = fullSize - 1
val byteRanges = requestHeaders.getValue("Range").substringAfter("=").split("-")
headers["Content-Range"] = "bytes ${byteRanges[0]}-$lastByte/$fullSize"
if (byteRanges.size == 1) {
headers["Connection"] = "close"
}
} else {
setStatusCodeAndReasonPhrase(HttpURLConnection.HTTP_OK, "OK")
}
responseHeaders = headers
}
}
fun copyReader(): ZimFileReader? = zimFile?.let(zimFileReaderFactory::create)

View File

@ -31,26 +31,25 @@
<TextView
android:id="@+id/no_open_book_text"
style="@style/no_content_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="@style/no_content"
android:text="@string/no_open_book"
android:visibility="gone"
android:layout_marginTop="@dimen/material_design_appbar_size"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.45" />
<Button
android:id="@+id/go_to_library_button_no_open_book"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/open_library"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/no_open_book_text" />
app:layout_constraintEnd_toEndOf="@+id/no_open_book_text"
app:layout_constraintStart_toStartOf="@+id/no_open_book_text"
app:layout_constraintTop_toBottomOf="@id/no_open_book_text"/>
<RelativeLayout
android:id="@+id/fullscreen_video_container"

View File

@ -1,7 +1,7 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
xmlns:tools="http://schemas.android.com/tools"
android:animateLayoutChanges="true"
android:fitsSystemWindows="true"
android:orientation="vertical">
@ -14,28 +14,25 @@
<include layout="@layout/layout_toolbar" />
<androidx.recyclerview.widget.RecyclerView
tools:listitem="@layout/list_item_search"
android:id="@+id/search_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
tools:listitem="@layout/list_item_search" />
</LinearLayout>
<TextView
android:id="@+id/searchNoResults"
style="@style/no_content_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="@style/no_content"
android:text="@string/no_results" />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/searchLoadingIndicator"
style="?android:attr/progressBarStyleLarge"
android:visibility="gone"
tools:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
android:layout_gravity="center"
android:visibility="gone"
tools:visibility="visible" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -33,6 +33,7 @@
<string name="hotspot_failed_title">فشل بدء الهوت-سبوت</string>
<string name="hotspot_failed_message">يبدو أن الهوت-سبوت مفعلٌ بالفعل. يرجى تعطيل هوت-سبوت الواي فاي للمتابعة.</string>
<string name="go_to_wifi_settings_label">انتقل إلى إعدادات الواي فاي</string>
<string name="connection_refused">الاتصال مرفوض.</string>
<string name="hotspot_running">تشغيل الهوت-سبوت</string>
<string name="no_books_selected_toast_message">يُرجى اختيار الكتب أولًا</string>
<string name="server_failed_message">لا يمكن بدء الخادم. يُرجى تشغيل الهوت-سبوت الخاص بك</string>
@ -76,6 +77,7 @@
<string name="delete_recent_search_item">حذف هذا العنصر؟</string>
<string name="pref_clear_all_history_title">إفراغ التاريخ</string>
<string name="pref_clear_all_history_summary">إفراغ عمليات البحث الحديثة وعلامات التبويب</string>
<string name="pref_notes">ملاحظات</string>
<string name="all_history_cleared">أُفرغ سجل التاريخ</string>
<string name="pref_clear_all_bookmarks_title">حذف الإشارات المرجعية</string>
<string name="clear_all_history_dialog_title">مسح كل التاريخ</string>
@ -227,6 +229,7 @@
<string name="severe_loss_error">خطأ شديد! حاول تعطيل/إعادة تمكين الواي فاي P2P</string>
<string name="connection_failed">فشل الاتصال</string>
<string name="permission_rationale_location">مطلوب إذن للموقع بواسطة أندرويد للسماح للتطبيق باكتشاف الأجهزة المقترنة</string>
<string name="permission_rationale_location_on_host_zim_file">مطلوب إذن للموقع بواسطة أندرويد للسماح للتطبيق باكتشاف ملفات زيم (Zim) المستضافة</string>
<string name="permission_refused_location">لا يمكن تحديد موقع الأجهزة المقترنة دون أذونات الموقع</string>
<string name="permission_refused_storage">لا يمكن الوصول إلى ملفات زيم (ZIM) دون إذن وحدة تخزين</string>
<string name="request_enable_location">تمكين الموقع للسماح باكتشاف الأجهزة المقترنة</string>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Authors:
* InsomniHat
* Kareyac
* ShockD
* StanProg
* Ted Masters
@ -48,6 +49,7 @@
<string name="delete_recent_search_item">Изтриване на този елемент?</string>
<string name="pref_clear_all_history_title">Изтрий история</string>
<string name="pref_clear_all_history_summary">Изтрийте последните търсения и история на табовете</string>
<string name="pref_notes">Бележки</string>
<string name="all_history_cleared">Историята е изтрита</string>
<string name="clear_all_history_dialog_title">Изтриване на цялата история?</string>
<string name="delete">Изтриване</string>

View File

@ -6,6 +6,7 @@
* FF11
* Killarnee
* Metalhead64
* Pittigrilli
* Stephane
* Susann Schweden
* Symposiarch
@ -74,6 +75,7 @@
<string name="delete_recent_search_item">Dieses Element löschen?</string>
<string name="pref_clear_all_history_title">Verlauf löschen</string>
<string name="pref_clear_all_history_summary">Letzte Suchanfragen und Registerkartenverlauf löschen</string>
<string name="pref_notes">Anmerkungen</string>
<string name="all_history_cleared">Gesamter Verlauf gelöscht</string>
<string name="pref_clear_all_bookmarks_title">Lesezeichen löschen</string>
<string name="clear_all_history_dialog_title">Gesamten Verlauf löschen?</string>

View File

@ -75,6 +75,7 @@
<string name="delete_recent_search_item">No item wa esterıyo?</string>
<string name="pref_clear_all_history_title">verore cı besterne</string>
<string name="pref_clear_all_history_summary">Cıgeyrayışê peyêni u Verocê tavaya bıesterne</string>
<string name="pref_notes">Noti</string>
<string name="all_history_cleared">Tarix pêro biyo pak</string>
<string name="pref_clear_all_bookmarks_title">Bookmarka pak kerê</string>
<string name="clear_all_history_dialog_title">Verori pêro wa pak kerê?</string>

View File

@ -4,6 +4,7 @@
* Geraki
* Giorgos456
* Glavkos
* NikosLikomitros
* Nikosgranturismogt
* Norhorn
-->
@ -68,6 +69,7 @@
<string name="delete_recent_search_item">Διαγραφή αυτού του αντικειμένου;</string>
<string name="pref_clear_all_history_title">Εκκαθάριση ιστορικού</string>
<string name="pref_clear_all_history_summary">Εκκαθάριση ιστορικού πρόσφατων αναζητήσεων και ετικετών</string>
<string name="pref_notes">Σημειώσεις</string>
<string name="all_history_cleared">Όλο το ιστορικό καθαρίστηκε</string>
<string name="clear_all_history_dialog_title" fuzzy="true">Εκκαθάριση όλου του ιστορικού</string>
<string name="delete">Διαγραφή</string>

View File

@ -3,6 +3,7 @@
* Abijeet Patro
* Blahma
* Fitoschido
* Javiero
* Kelson
* KuboF
* Mirin
@ -49,6 +50,7 @@
<string name="delete_recent_search_item">Forigi ĉi tiu eron?</string>
<string name="pref_clear_all_history_title">Forviŝi hisorion</string>
<string name="pref_clear_all_history_summary">Forviŝi ĵusajn serĉojn kaj historion de langetoj</string>
<string name="pref_notes">Notoj</string>
<string name="all_history_cleared">Forviŝis Ĉiun Historion</string>
<string name="clear_all_history_dialog_title" fuzzy="true">Forviŝi Ĉiun da Historio</string>
<string name="share">Diskonigi</string>

View File

@ -12,6 +12,7 @@
* MarcoAurelio
* Mpayansilva
* Ncr
* Rodney Araujo
* VegaDark
-->
<resources>
@ -76,6 +77,7 @@
<string name="delete_recent_search_item">¿Borrar este elemento?</string>
<string name="pref_clear_all_history_title">Limpiar el historial</string>
<string name="pref_clear_all_history_summary">Borrar las búsquedas recientes y el historial de pestañas</string>
<string name="pref_notes">Notas</string>
<string name="all_history_cleared">Borrado todo el historial</string>
<string name="pref_clear_all_bookmarks_title">Borrar marcadores</string>
<string name="clear_all_history_dialog_title">Borrar todo el historial?</string>

View File

@ -84,6 +84,7 @@
<string name="delete_recent_search_item">Supprimer cet élément?</string>
<string name="pref_clear_all_history_title">Effacer lhistorique</string>
<string name="pref_clear_all_history_summary">Effacer les recherches récentes et lhistorique des onglets</string>
<string name="pref_notes">Notes</string>
<string name="all_history_cleared">Tout lhistorique est effacé</string>
<string name="pref_clear_all_bookmarks_title">Supprimer les marque-pages</string>
<string name="clear_all_history_dialog_title">Effacer tout lhistorique ?</string>

View File

@ -50,6 +50,7 @@
<string name="clear_recent_and_tabs_history_dialog">Sei sicuro di voler cancellare la tua cronologia di ricerca e resettare tutte le tab attive?</string>
<string name="delete_recent_search_item">Elimina questo elemento?</string>
<string name="pref_clear_all_history_title">Cancella la cronologia</string>
<string name="pref_notes">Note</string>
<string name="all_history_cleared">Tutta la cronologia è stata cancellata</string>
<string name="clear_all_history_dialog_title">Cancellare tutta la cronologia?</string>
<string name="delete">Cancella</string>

View File

@ -9,6 +9,7 @@
* Tuvalevsku
* YaronSh
* יאיר מן
* ישראל קלר
-->
<resources>
<string name="menu_help">עזרה</string>
@ -77,6 +78,7 @@
<string name="delete_recent_search_item">למחוק את הפריט הזה?</string>
<string name="pref_clear_all_history_title">ניקוי ההיסטוריה</string>
<string name="pref_clear_all_history_summary">ניקוי מילות חיפוש קודמות והיסטוריית כרטיסיות</string>
<string name="pref_notes">הערות</string>
<string name="all_history_cleared">כל ההיסטוריה נמחקה</string>
<string name="pref_clear_all_bookmarks_title">ניקוי סימניות</string>
<string name="clear_all_history_dialog_title">לנקות את כל ההיסטוריה?</string>

View File

@ -52,7 +52,7 @@
<string name="server_started_message">Vê adresa IPyê di geroka xwe de binivîsîne ji bo ku xwe bigihînî servera %s</string>
<string name="error_file_not_found">Çewtîː Peldanka ZIM\'ê ya bijartî nehate dîtin.</string>
<string name="zim_not_opened">Nikare dosyeya zim-ê veke</string>
<string name="error_file_invalid">Çewtîː Peldanka bijartî ne peldankeke ZIM\'ê ya derbasdar e.</string>
<string name="error_file_invalid">Çewtîː Peldanka bijartî ne peldankeke ZIMê ya derbasdar e.</string>
<string name="error_article_url_not_found">Çewtîː Barkirina gotara (Url: %1$s) têk çû.</string>
<string name="pref_display_title">Nîşan bide</string>
<string name="pref_info_title">Agahî</string>
@ -73,6 +73,7 @@
<string name="delete_recent_search_item">Vê pelê jê bibe?</string>
<string name="pref_clear_all_history_title">Raboriyê paqij bike</string>
<string name="pref_clear_all_history_summary">Lêgerînên dawî û raboriya hilpekînan paqij bike</string>
<string name="pref_notes">Not</string>
<string name="all_history_cleared">Hemû Raborî Hat Paqijkirin</string>
<string name="pref_clear_all_bookmarks_title">Bijareyan paqij bike</string>
<string name="clear_all_history_dialog_title">Hemû Dîrokê Paqij Bike</string>

View File

@ -39,6 +39,7 @@
<string name="pref_language_chooser">Sicht eng Sprooch eraus</string>
<string name="pref_credits">Auteuren a Lizenzen</string>
<string name="delete_recent_search_item">Dëst Element läschen?</string>
<string name="pref_notes">Notizen</string>
<string name="pref_clear_all_bookmarks_title">Lieszeechen ewechhuelen</string>
<string name="delete">Läschen</string>
<string name="cancel">Ofbriechen</string>

View File

@ -70,6 +70,7 @@
<string name="delete_recent_search_item">Да ја избришам ставкава?</string>
<string name="pref_clear_all_history_title">Исчисти историја</string>
<string name="pref_clear_all_history_summary">Исчисти скорешни пребарувања и јазичиња</string>
<string name="pref_notes">Белешки</string>
<string name="all_history_cleared">Сета историја е исчистена</string>
<string name="pref_clear_all_bookmarks_title">Исчисти обележувачи</string>
<string name="clear_all_history_dialog_title">Да ја исчистам сета историја</string>

View File

@ -4,6 +4,7 @@
* Alan ffm
* DeRudySoulStorm
* InternerowyGołąb
* Kareyac
* Kelson
* Krzyz23
* Macofe
@ -79,6 +80,7 @@
<string name="delete_recent_search_item">Usunąć ten obiekt?</string>
<string name="pref_clear_all_history_title">Wyczyść historię</string>
<string name="pref_clear_all_history_summary">Wyczyść historię ostatnich wyszukiwań i kart</string>
<string name="pref_notes">Uwagi</string>
<string name="all_history_cleared">Usunięto całą historię</string>
<string name="pref_clear_all_bookmarks_title">Wyczyść zakładki</string>
<string name="clear_all_history_dialog_title">Wyczyść całą historię?</string>

View File

@ -76,6 +76,7 @@
<string name="delete_recent_search_item">Eliminar este item?</string>
<string name="pref_clear_all_history_title">Apagar histórico</string>
<string name="pref_clear_all_history_summary">Limpar pesquisas recentes e histórico de guias</string>
<string name="pref_notes">Notas</string>
<string name="all_history_cleared">Eliminando todo o histórico</string>
<string name="pref_clear_all_bookmarks_title">Limpar marcadores</string>
<string name="clear_all_history_dialog_title">Limpar todo o histórico?</string>

View File

@ -7,6 +7,7 @@
* Hamilton Abreu
* Imperadeiro90
* Imperadeiro98
* Kareyac
* Kelson
* Macofe
* Mansil alfalb
@ -53,6 +54,7 @@
<string name="delete_recent_search_item">Apagar este elemento?</string>
<string name="pref_clear_all_history_title">Limpar o histórico</string>
<string name="pref_clear_all_history_summary">Limpar as pesquisas recentes e o histórico de separadores</string>
<string name="pref_notes">Notas</string>
<string name="all_history_cleared">Todo o historial foi apagado</string>
<string name="clear_all_history_dialog_title" fuzzy="true">Apagar todo o historial</string>
<string name="delete">Apagar</string>

View File

@ -29,6 +29,7 @@
<string name="pref_back_to_top">{{Identical|Back to top}}</string>
<string name="pref_language_title">{{Identical|Language}}</string>
<string name="pref_language_chooser">{{Identical|Choose language}}</string>
<string name="pref_notes">{{Identical|Notes}}</string>
<string name="delete">{{Identical|Delete}}</string>
<string name="cancel">{{identical|Cancel}}</string>
<string name="undo">{{Identical|Undo}}</string>
@ -45,6 +46,7 @@
<string name="previous">{{Identical|Previous}}</string>
<string name="time_left">This is the past participle of the verb “to leave” (meaning “quitted” or “exited”). This is used in a context of “X minutes left” to finish a download.</string>
<string name="time_yesterday">{{Identical|Yesterday}}</string>
<string name="history">{{Identical|History}}</string>
<string name="search_history">TODO: Unclear, must be documented. See https://github.com/kiwix/overview/issues/31</string>
<string name="save">{{Identical|Save}}</string>
<string name="permission_rationale_location_on_host_zim_file">Tell the user Location permission required for hosting zim file.</string>

View File

@ -85,6 +85,7 @@
<string name="delete_recent_search_item">Удалить этот элемент?</string>
<string name="pref_clear_all_history_title">Очистить историю</string>
<string name="pref_clear_all_history_summary">Очистить недавние поисковые запросы и историю вкладок</string>
<string name="pref_notes">Примечания</string>
<string name="all_history_cleared">Вся история очищена</string>
<string name="pref_clear_all_bookmarks_title">Очистить закладки</string>
<string name="clear_all_history_dialog_title">Очистить всю историю?</string>

View File

@ -156,7 +156,7 @@
<string name="table_of_contents">Kazalo vsebine</string>
<string name="select_languages">Izberi jezike</string>
<string name="save_languages">Shrani jezike</string>
<string name="send_feedback">Sporoči svoje mnenje</string>
<string name="send_feedback">Sporočite svoje mnenje</string>
<string name="expand">Razširi</string>
<string name="history">Zgodovina</string>
<string name="history_from_current_book" fuzzy="true">Zgodovina iz trenutne knjige</string>

View File

@ -75,6 +75,7 @@
<string name="delete_recent_search_item">Radera detta objekt?</string>
<string name="pref_clear_all_history_title">Rensa historik</string>
<string name="pref_clear_all_history_summary">Rensa senaste sökningar och flikhistorik</string>
<string name="pref_notes">Anteckningar</string>
<string name="all_history_cleared">All historik rensades</string>
<string name="pref_clear_all_bookmarks_title">Rensa bokmärken</string>
<string name="clear_all_history_dialog_title">Rensa all historik?</string>

View File

@ -83,6 +83,7 @@
<string name="delete_recent_search_item">Bu öğe silinsin mi?</string>
<string name="pref_clear_all_history_title">Geçmişi temizle</string>
<string name="pref_clear_all_history_summary">Son aramalar ve sekmeler geçmişini temizle</string>
<string name="pref_notes">Notlar</string>
<string name="all_history_cleared">Tüm geçmiş temizlendi</string>
<string name="pref_clear_all_bookmarks_title">Yer imlerini temizle</string>
<string name="clear_all_history_dialog_title">Tüm Geçmişi Silinsin mi?</string>

View File

@ -75,6 +75,7 @@
<string name="delete_recent_search_item">刪除此項目?</string>
<string name="pref_clear_all_history_title">清除歷史記錄</string>
<string name="pref_clear_all_history_summary">清除近期搜尋和分頁歷史記錄</string>
<string name="pref_notes">備註</string>
<string name="all_history_cleared">所有歷史記錄已清除</string>
<string name="pref_clear_all_bookmarks_title">清除書籤</string>
<string name="clear_all_history_dialog_title">清除所有歷史記錄?</string>

View File

@ -18,4 +18,6 @@
<dimen name="section_list_height">56dp</dimen>
<dimen name="card_margin">5dp</dimen>
<dimen name="fab_vertical_offset">25dp</dimen>
<dimen name="material_design_appbar_size">48dp</dimen>
</resources>

View File

@ -66,6 +66,7 @@
<string name="delete_recent_search_item">Delete this item?</string>
<string name="pref_clear_all_history_title">Clear history</string>
<string name="pref_clear_all_history_summary">Clear recent searches and tabs history</string>
<string name="pref_notes">Notes</string>
<string name="all_history_cleared">All History Cleared</string>
<string name="pref_clear_all_bookmarks_title">Clear bookmarks</string>
<string name="clear_all_history_dialog_title">Clear All History?</string>

View File

@ -62,7 +62,6 @@
<item name="android:gravity">end</item>
</style>
<style name="no_content_text" parent="TextAppearance.KiwixTheme.Headline5" />
<style name="switch_style">
<item name="android:layout_width">wrap_content</item>
@ -104,4 +103,11 @@
<item name="colorAccent">@color/denim_blue400</item>
</style>
<style name="no_content" parent="TextAppearance.KiwixTheme.Headline6">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center</item>
<item name="android:visibility">gone</item>
</style>
</resources>

View File

@ -74,7 +74,7 @@
<PreferenceCategory
android:key="pref_history"
android:title="History"
android:title="@string/history"
app:iconSpaceReserved="false">
<Preference
@ -86,7 +86,7 @@
</PreferenceCategory>
<PreferenceCategory
android:key="pref_notes"
android:title="Notes"
android:title="@string/pref_notes"
app:iconSpaceReserved="false">
<Preference

View File

@ -24,9 +24,12 @@
<a href="mailto:adeelzafar619@gmail.com">Adeel Zafar</a><br>
<a href="mailto:sood.aditya.08@gmail.com">Aditya Sood</a><br>
<a href="mailto:ayoubuto@gmail.com">Ayoub Dardory</a><br>
<a href="mailto:stvayush@gmail.com">Ayush Shrivastava</a><br>
<a href="mailto:cip@gmx.at">Christian Pühringer</a><br>
<a href="mailto:elad.keyshawn@gmail.com">Elad Keyshawn</a><br>
<a href="mailto:kelson@kiwix.org">Emmanuel Engelhart</a><br>
<a href="mailto:franslukas@pm.me">Frans-Lukas Lövenvald</a><br>
<a href="mailto:gouripanda4@gmail.com">Gourishankar Panda</a><br>
<a href="mailto:mhutti1@gmail.com">Isaac Hutt</a><br>
<a href="mailto:joseph.reeve@googlemail.com">Joseph E. Reeve</a><br>
<a href="mailto:julianharty@gmail.com">Julian Harty</a><br>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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/>.
~
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<!-- The background color, preferably the same as your normal theme -->
<item android:drawable="@color/alabaster_white" />
<item
android:bottom="24dp"
android:drawable="@mipmap/ic_launcher"
android:gravity="center"
android:left="24dp"
android:right="24dp"
android:top="24dp" />
</layer-list>

View File

@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ 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
@ -21,11 +20,9 @@
android:opacity="opaque">
<!-- The background color, preferably the same as your normal theme -->
<item android:drawable="@color/mine_shaft_gray900" />
<item
android:bottom="24dp"
android:drawable="@mipmap/ic_launcher"
android:gravity="center"
android:left="24dp"
android:right="24dp"
android:top="24dp" />
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher" />
</item>
</layer-list>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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/>.
~
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<!-- The background color, preferably the same as your normal theme -->
<item android:drawable="@color/alabaster_white" />
<item
android:bottom="24dp"
android:drawable="@mipmap/ic_launcher"
android:gravity="center"
android:left="24dp"
android:right="24dp"
android:top="24dp" />
</layer-list>

View File

@ -21,11 +21,9 @@
android:opacity="opaque">
<!-- The background color, preferably the same as your normal theme -->
<item android:drawable="@color/alabaster_white" />
<item
android:bottom="24dp"
android:drawable="@mipmap/ic_launcher"
android:gravity="center"
android:left="24dp"
android:right="24dp"
android:top="24dp" />
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher" />
</item>
</layer-list>