diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index 2d5b808bc..000000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Fill out this template with your issue then delete these lines only leaving the titles and your responses.
-
-# For a Bug Report:
-
-## Bug Report
-
-### Are you ready to report?
- - Your issue may already be reported! Please search on the [issue track](../) before creating one.
- - Ensure you have tested with the last (dev) version of the software. (If not, and if possible, run your test again with the most recent version available.)
-
-### Environment
- * version of the software you use : _____
- * device / operating system : _____
-
-### The Bug:
-
- * What do you obtain? A copy of the error message or a screenshot is always useful.
-
- * When does this occur?
-
-#### Steps to reproduce:
-
- 1. _____
- 2. _____
- 3. _____
- ...
-
- * What should be the behaviour from your point of view? How do you expect the service to work?
-
-
-### Other Comments:
- * What is the context of this ticket? If not obvious, explain why you need to do this.
-
- * If you have an idea about the technical background of the ticket, please share it.
-
-
-# For a Feature Request:
-
-## Feature Request
-
-#### Feature Description
-
-Please describe the feature you want to add to the project.
-
-
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 000000000..5bc91e633
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,35 @@
+---
+name: Bug report
+about: Create a report to help us improve
+
+---
+
+
+
+**Describe the bug**
+
+
+**Expected behavior**
+
+
+**Steps to reproduce the behavior:**
+1.
+
+
+**Screenshots**
+
+
+**Environment**
+- Version of Kiwix Android :
+- Device :
+- OS version :
+
+**Logs**
+
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 000000000..e3fae4acf
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,23 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+
+---
+
+
+**Is your feature request related to a problem? Please describe.**
+
+
+**Describe the solution you'd like**
+
+
+**Describe alternatives you've considered**
+
+
+**Additional context**
+
diff --git a/.github/ISSUE_TEMPLATE/test_request.md b/.github/ISSUE_TEMPLATE/test_request.md
new file mode 100644
index 000000000..6ddbaedc1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/test_request.md
@@ -0,0 +1,31 @@
+---
+name: Request Tests
+about: Identify code liable to break and create tests to prevent software regression due to code changes
+
+---
+
+
+
+**Type of Test**
+
+* [ ] Unit Test
+* [ ] UI Test
+
+**Particular area and files to be tested**
+
+
+**Current Status of the tests**
+
+
+**Particular Behaviour to be tested**
+
\ No newline at end of file
diff --git a/CHANGELOG b/CHANGELOG
index c45c86e1f..901aff1f3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,4 @@
-2.3
+2.4
FIX: External SD card problems
FIX: Some UI translation
FIX: Download manager process sporadic problems
diff --git a/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/tests/BasicTest.java b/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/tests/BasicTest.java
index 1dd04566b..aa55f8074 100644
--- a/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/tests/BasicTest.java
+++ b/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/tests/BasicTest.java
@@ -76,7 +76,7 @@ public class BasicTest {
openDrawerWithGravity(R.id.drawer_layout, Gravity.RIGHT);
assertDrawerIsOpenWithGravity(R.id.drawer_layout, Gravity.RIGHT);
- assertDisplayed(R.string.no_section_info);
+ assertDisplayed(R.string.menu_help);
closeDrawerWithGravity(R.id.drawer_layout, Gravity.RIGHT);
assertDrawerIsClosedWithGravity(R.id.drawer_layout, Gravity.RIGHT);*/
diff --git a/app/src/main/assets/home.html b/app/src/main/assets/home.html
index 491d4ef2a..b478bb5bf 100644
--- a/app/src/main/assets/home.html
+++ b/app/src/main/assets/home.html
@@ -2,6 +2,9 @@
- Home
+ REPLACE_menu_home
+
+REPLACE_menu_home
+
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/base/BaseActivity.java b/app/src/main/java/org/kiwix/kiwixmobile/base/BaseActivity.java
index 5f58db670..3a35d6706 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/base/BaseActivity.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/base/BaseActivity.java
@@ -23,6 +23,7 @@ import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import org.kiwix.kiwixmobile.R;
+import org.kiwix.kiwixmobile.utils.LanguageUtils;
import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil;
import javax.inject.Inject;
@@ -42,6 +43,7 @@ public abstract class BaseActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
+ LanguageUtils.handleLocaleChange(this, sharedPreferenceUtil);
}
@Override
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/data/local/KiwixDatabase.java b/app/src/main/java/org/kiwix/kiwixmobile/data/local/KiwixDatabase.java
index 671063c0a..02aa4ebc0 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/data/local/KiwixDatabase.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/data/local/KiwixDatabase.java
@@ -36,6 +36,7 @@ import org.kiwix.kiwixmobile.data.local.entity.LibraryDatabaseEntity;
import org.kiwix.kiwixmobile.data.local.entity.NetworkLanguageDatabaseEntity;
import org.kiwix.kiwixmobile.data.local.entity.RecentSearch;
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
+import org.kiwix.kiwixmobile.utils.UpdateUtils;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
@@ -52,7 +53,7 @@ import static org.kiwix.kiwixmobile.utils.Constants.TAG_KIWIX;
@Singleton
public class KiwixDatabase extends SquidDatabase {
- private static final int VERSION = 16;
+ private static final int VERSION = 17;
private final Context context;
@Inject
@@ -125,6 +126,8 @@ public class KiwixDatabase extends SquidDatabase {
tryAddColumn(Bookmark.ZIM_FILE_PATH);
tryAddColumn(Bookmark.FAVICON);
migrateBookmarksVersion16();
+ case 16:
+ new BookmarksDao(this).processBookmark(UpdateUtils::reformatProviderUrl);
}
return true;
}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/data/local/dao/BookmarksDao.java b/app/src/main/java/org/kiwix/kiwixmobile/data/local/dao/BookmarksDao.java
index 21a84fab7..fae480508 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/data/local/dao/BookmarksDao.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/data/local/dao/BookmarksDao.java
@@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.data.local.dao;
import com.yahoo.squidb.data.SquidCursor;
import com.yahoo.squidb.sql.Query;
+import com.yahoo.squidb.sql.Update;
import org.kiwix.kiwixmobile.data.ZimContentProvider;
import org.kiwix.kiwixmobile.data.local.KiwixDatabase;
@@ -107,4 +108,23 @@ public class BookmarksDao {
kiwixDatabase.deleteWhere(Bookmark.class, Bookmark.BOOKMARK_URL.eq(bookmark.getBookmarkUrl())
.and(Bookmark.ZIM_ID.eq(bookmark.getZimId())));
}
+
+ public void processBookmark(StringOperation operation) {
+ try (SquidCursor bookmarkCursor = kiwixDatabase.query(Bookmark.class,
+ Query.select(Bookmark.ID, Bookmark.BOOKMARK_URL))) {
+ while (bookmarkCursor.moveToNext()) {
+ String url = bookmarkCursor.get(Bookmark.BOOKMARK_URL);
+ url = operation.apply(url);
+ if (url != null) {
+ kiwixDatabase.update(Update.table(Bookmark.TABLE)
+ .where(Bookmark.ID.eq(bookmarkCursor.get(Bookmark.ID)))
+ .set(Bookmark.BOOKMARK_URL, url));
+ }
+ }
+ }
+ }
+
+ public interface StringOperation {
+ String apply(String string);
+ }
}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/downloader/ChunkUtils.java b/app/src/main/java/org/kiwix/kiwixmobile/downloader/ChunkUtils.java
index 2731e2897..06d4b3923 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/downloader/ChunkUtils.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/downloader/ChunkUtils.java
@@ -26,7 +26,7 @@ public class ChunkUtils {
public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
public static final String ZIM_EXTENSION = ".zim";
- public static final String PART = ".part";
+ public static final String PART = ".part.part";
public static final long CHUNK_SIZE = 1024L * 1024L * 1024L * 2L;
public static List getChunks(String url, long contentLength, int notificationID) {
@@ -63,7 +63,7 @@ public class ChunkUtils {
private static String[] getZimChunkFileNames(String fileName, int count) {
if (count == 1) {
- return new String[] { fileName + PART};
+ return new String[]{fileName + PART};
}
int position = fileName.lastIndexOf(".");
String baseName = position > 0 ? fileName.substring(0, position) : fileName;
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/downloader/DownloadService.java b/app/src/main/java/org/kiwix/kiwixmobile/downloader/DownloadService.java
index b083156f8..e158002d3 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/downloader/DownloadService.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/downloader/DownloadService.java
@@ -71,6 +71,9 @@ import okhttp3.Request;
import okhttp3.Response;
import okio.BufferedSource;
+import static org.kiwix.kiwixmobile.downloader.ChunkUtils.ALPHABET;
+import static org.kiwix.kiwixmobile.downloader.ChunkUtils.PART;
+import static org.kiwix.kiwixmobile.downloader.ChunkUtils.ZIM_EXTENSION;
import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_BOOK;
import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_LIBRARY;
import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_NOTIFICATION_ID;
@@ -139,8 +142,7 @@ public class DownloadService extends Service {
if (intent == null) {
return START_NOT_STICKY;
}
- String log = intent.getAction();
- log += " : ";
+ String log = intent.getAction() + " : ";
if (intent.hasExtra(NOTIFICATION_ID)) {
log += intent.getIntExtra(NOTIFICATION_ID, -3);
}
@@ -322,6 +324,35 @@ public class DownloadService extends Service {
notification.get(notificationID).setContentText(getString(R.string.zim_file_downloaded));
final Intent target = new Intent(DownloadService.this, MainActivity.class);
target.putExtra(EXTRA_ZIM_FILE, KIWIX_ROOT + StorageUtils.getFileNameFromUrl(book.getUrl()));
+ //Remove the extra ".part" from files
+ String filename = book.file.getPath();
+ if (filename.endsWith(ZIM_EXTENSION)) {
+ filename = filename + PART;
+ File partFile = new File(filename);
+ if (partFile.exists()) {
+ partFile.renameTo(new File(partFile.getPath().replaceAll(".part", "")));
+ }
+ } else {
+ for (int i = 0; true; i++) {
+ char first = ALPHABET.charAt(i / 26);
+ char second = ALPHABET.charAt(i % 26);
+ String chunkExtension = String.valueOf(first) + second;
+ filename = book.file.getPath();
+ filename = filename.replaceAll(".zim([a-z][a-z]){0,1}$", ".zim");
+ filename = filename + chunkExtension + ".part";
+ File partFile = new File(filename);
+ if (partFile.exists()) {
+ partFile.renameTo(new File(partFile.getPath().replaceAll(".part$", "")));
+ } else {
+ File lastChunkFile = new File(filename + ".part");
+ if (lastChunkFile.exists()) {
+ lastChunkFile.renameTo(new File(partFile.getPath().replaceAll(".part", "")));
+ } else {
+ break;
+ }
+ }
+ }
+ }
target.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
PendingIntent pendingIntent = PendingIntent.getActivity
(getBaseContext(), 0,
@@ -453,7 +484,7 @@ public class DownloadService extends Service {
// Create chunk file
File file = new File(KIWIX_ROOT, chunk.getFileName());
file.getParentFile().mkdirs();
- File fullFile = new File(file.getPath().substring(0, file.getPath().length() - 5));
+ File fullFile = new File(file.getPath().substring(0, file.getPath().length() - PART.length()));
long downloaded = Long.parseLong(chunk.getRangeHeader().split("-")[0]);
if (fullFile.exists() && fullFile.length() == chunk.getSize()) {
@@ -535,7 +566,8 @@ public class DownloadService extends Service {
break;
}
- if (MainActivity.wifiOnly && !NetworkUtils.isWiFi(getApplicationContext())) {
+ if (MainActivity.wifiOnly && !NetworkUtils.isWiFi(getApplicationContext()) ||
+ !NetworkUtils.isNetworkAvailable(getApplicationContext())) {
pauseDownload(chunk.getNotificationID());
}
@@ -594,16 +626,16 @@ public class DownloadService extends Service {
if (downloadStatus.get(chunk.getNotificationID()) == CANCEL) {
String path = file.getPath();
Log.i(KIWIX_TAG, "Download Cancelled, deleting file: " + path);
- if (path.substring(path.length() - 8).equals("zim.part")) {
- path = path.substring(0, path.length() - 5);
+ if (path.substring(path.length() - (ZIM_EXTENSION + PART).length()).equals(ZIM_EXTENSION + PART)) {
+ path = path.substring(0, path.length() - PART.length() + 1);
FileUtils.deleteZimFile(path);
} else {
- path = path.substring(0, path.length() - 7) + "aa";
+ path = path.substring(0, path.length() - (ZIM_EXTENSION + PART).length() + 2) + "aa";
FileUtils.deleteZimFile(path);
}
} else {
- Log.i(KIWIX_TAG, "Download completed, renaming file ([" + file.getPath() + "] -> .zim)");
- file.renameTo(new File(file.getPath().replace(".part", "")));
+ Log.i(KIWIX_TAG, "Download completed, renaming file ([" + file.getPath() + "] -> .zim.part)");
+ file.renameTo(new File(file.getPath().replaceAll(".part$", "")));
}
// Mark chunk status as downloaded
chunk.isDownloaded = true;
@@ -627,6 +659,7 @@ public class DownloadService extends Service {
NotificationChannel ongoingDownloadsChannel = new NotificationChannel(
Constants.ONGOING_DOWNLOAD_CHANNEL_ID, name, importance);
ongoingDownloadsChannel.setDescription(description);
+ ongoingDownloadsChannel.setSound(null, null);
NotificationManager notificationManager = (NotificationManager) getSystemService(
NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(ongoingDownloadsChannel);
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/main/MainActivity.java b/app/src/main/java/org/kiwix/kiwixmobile/main/MainActivity.java
index cfe2d11a9..33f9d5644 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/main/MainActivity.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/main/MainActivity.java
@@ -140,7 +140,9 @@ import static org.kiwix.kiwixmobile.utils.Constants.TAG_CURRENT_POSITIONS;
import static org.kiwix.kiwixmobile.utils.Constants.TAG_CURRENT_TAB;
import static org.kiwix.kiwixmobile.utils.Constants.TAG_FILE_SEARCHED;
import static org.kiwix.kiwixmobile.utils.Constants.TAG_KIWIX;
+import static org.kiwix.kiwixmobile.utils.LanguageUtils.getResourceString;
import static org.kiwix.kiwixmobile.utils.StyleUtils.dialogStyle;
+import static org.kiwix.kiwixmobile.utils.UpdateUtils.reformatProviderUrl;
public class MainActivity extends BaseActivity implements WebViewCallback,
MainContract.View, BooksAdapter.OnItemClickListener {
@@ -321,6 +323,7 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter.attachView(this);
+ new WebView(this).destroy(); // Workaround for buggy webViews see #710
wifiOnly = sharedPreferenceUtil.getPrefWifiOnly();
nightMode = sharedPreferenceUtil.nightMode();
handleLocaleCheck();
@@ -346,25 +349,8 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
tableDrawerRight.setLayoutManager(new LinearLayoutManager(this));
- TableDrawerAdapter tableDrawerAdapter = new TableDrawerAdapter();
+ TableDrawerAdapter tableDrawerAdapter = setupTableDrawerAdapter();
tableDrawerRight.setAdapter(tableDrawerAdapter);
- tableDrawerAdapter.setTableClickListener(new TableClickListener() {
- @Override
- public void onHeaderClick(View view) {
- getCurrentWebView().setScrollY(0);
- drawerLayout.closeDrawer(GravityCompat.END);
- }
-
- @Override
- public void onSectionClick(View view, int position) {
- getCurrentWebView().loadUrl("javascript:document.getElementById('"
- + documentSections.get(position).id
- + "').scrollIntoView();");
-
- drawerLayout.closeDrawers();
- }
- });
-
tableDrawerAdapter.notifyDataSetChanged();
tabsAdapter.setTabClickListener(new TabsAdapter.TabClickListener() {
@@ -391,8 +377,17 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
documentParser = new DocumentParser(new DocumentParser.SectionsListener() {
@Override
public void sectionsLoaded(String title, List sections) {
+ for (DocumentSection section : sections) {
+ if (section.title.contains("REPLACE_")) {
+ section.title = getResourceString(getApplicationContext(), section.title);
+ }
+ }
documentSections.addAll(sections);
- tableDrawerAdapter.setTitle(title);
+ if (title.contains("REPLACE_")) {
+ tableDrawerAdapter.setTitle(getResourceString(getApplicationContext(), title));
+ } else {
+ tableDrawerAdapter.setTitle(title);
+ }
tableDrawerAdapter.setSections(documentSections);
tableDrawerAdapter.notifyDataSetChanged();
}
@@ -443,6 +438,26 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
new ItemTouchHelper(tabCallback).attachToRecyclerView(tabRecyclerView);
}
+ private TableDrawerAdapter setupTableDrawerAdapter() {
+ TableDrawerAdapter tableDrawerAdapter = new TableDrawerAdapter();
+ tableDrawerAdapter.setTableClickListener(new TableClickListener() {
+ @Override
+ public void onHeaderClick(View view) {
+ getCurrentWebView().setScrollY(0);
+ drawerLayout.closeDrawer(GravityCompat.END);
+ }
+
+ @Override
+ public void onSectionClick(View view, int position) {
+ getCurrentWebView().loadUrl("javascript:document.getElementById('"
+ + documentSections.get(position).id
+ + "').scrollIntoView();");
+ drawerLayout.closeDrawers();
+ }
+ });
+ return tableDrawerAdapter;
+ }
+
private void showTabSwitcher() {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(ContextCompat.getDrawable(this, R.drawable.ic_round_add_white_36dp));
@@ -750,7 +765,7 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
}
}
- private KiwixWebView getCurrentWebView() {
+ KiwixWebView getCurrentWebView() {
if (webViewList.size() == 0) return newTab();
if (currentWebViewIndex < webViewList.size()) {
return webViewList.get(currentWebViewIndex);
@@ -1191,18 +1206,19 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
intent.setAction("");
goToSearch(true);
break;
- case Intent.ACTION_VIEW: {
- final String zimFile = ZimContentProvider.getZimFile();
- saveTabStates();
- Intent i = new Intent(MainActivity.this, SearchActivity.class);
- i.putExtra(EXTRA_ZIM_FILE, zimFile);
- if (intent.getData() != null) {
- i.putExtra(EXTRA_SEARCH, intent.getData().getLastPathSegment());
+ case Intent.ACTION_VIEW:
+ if (intent.getType() == null || !intent.getType().equals("application/octet-stream")) {
+ final String zimFile = ZimContentProvider.getZimFile();
+ saveTabStates();
+ Intent i = new Intent(MainActivity.this, SearchActivity.class);
+ i.putExtra(EXTRA_ZIM_FILE, zimFile);
+ if (intent.getData() != null) {
+ i.putExtra(EXTRA_SEARCH, intent.getData().getLastPathSegment());
+ }
+ intent.setAction("");
+ startActivityForResult(i, REQUEST_FILE_SEARCH);
}
- intent.setAction("");
- startActivityForResult(i, REQUEST_FILE_SEARCH);
break;
- }
case NEW_TAB:
newTab(HOME_URL);
break;
@@ -1602,11 +1618,11 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
JSONArray urls = new JSONArray(zimArticles);
JSONArray positions = new JSONArray(zimPositions);
int i = 0;
- getCurrentWebView().loadUrl(urls.getString(i));
+ getCurrentWebView().loadUrl(reformatProviderUrl(urls.getString(i)));
getCurrentWebView().setScrollY(positions.getInt(i));
i++;
for (; i < urls.length(); i++) {
- newTab(urls.getString(i));
+ newTab(reformatProviderUrl(urls.getString(i)));
getCurrentWebView().setScrollY(positions.getInt(i));
}
selectTab(currentTab);
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/main/TableDrawerAdapter.java b/app/src/main/java/org/kiwix/kiwixmobile/main/TableDrawerAdapter.java
index 4e3718185..cf1b820a1 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/main/TableDrawerAdapter.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/main/TableDrawerAdapter.java
@@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.main;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Typeface;
+import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.LayoutInflater;
@@ -45,7 +46,7 @@ public class TableDrawerAdapter extends RecyclerView.Adapter();
}
@@ -54,8 +55,9 @@ public class TableDrawerAdapter extends RecyclerView.Adapter {
@@ -152,14 +157,14 @@ public class TableDrawerAdapter extends RecyclerView.Adapter {
@@ -113,7 +114,11 @@ public class TabsAdapter extends RecyclerView.Adapter {
if (webView.getParent() != null) {
((ViewGroup) webView.getParent()).removeView(webView);
}
- holder.title.setText(fromHtml(webView.getTitle()));
+ String webViewTitle = fromHtml(webView.getTitle()).toString();
+ if (webViewTitle.contains("REPLACE_")) {
+ webViewTitle = getResourceString(holder.title.getContext().getApplicationContext(), webViewTitle);
+ }
+ holder.title.setText(webViewTitle);
holder.close.setOnClickListener(v -> listener.onCloseTab(v, holder.getAdapterPosition()));
holder.content.setImageBitmap(getBitmapFromView(webView));
holder.content.setOnClickListener(v -> {
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/search/SearchActivity.java b/app/src/main/java/org/kiwix/kiwixmobile/search/SearchActivity.java
index 7a57de3b1..8a6e58327 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/search/SearchActivity.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/search/SearchActivity.java
@@ -29,7 +29,6 @@ import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.Html;
-import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -63,9 +62,10 @@ public class SearchActivity extends BaseActivity
public static final String EXTRA_SEARCH_IN_TEXT = "bool_searchintext";
private final int REQ_CODE_SPEECH_INPUT = 100;
- private ListView mListView;
- private AutoCompleteAdapter mAutoAdapter;
- private ArrayAdapter mDefaultAdapter;
+ private ListView listView;
+ private ArrayAdapter currentAdapter;
+ private AutoCompleteAdapter autoAdapter;
+ private ArrayAdapter defaultAdapter;
private SearchView searchView;
private String searchText;
@@ -85,14 +85,14 @@ public class SearchActivity extends BaseActivity
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_back);
getSupportActionBar().setHomeButtonEnabled(true);
searchPresenter.attachView(this);
- mListView = findViewById(R.id.search_list);
- mDefaultAdapter = getDefaultAdapter();
+ listView = findViewById(R.id.search_list);
+ defaultAdapter = getDefaultAdapter();
searchPresenter.getRecentSearches();
- mListView.setAdapter(mDefaultAdapter);
+ activateDefaultAdapter();
- mAutoAdapter = new AutoCompleteAdapter(this);
- mListView.setOnItemClickListener(this);
- mListView.setOnItemLongClickListener(this);
+ autoAdapter = new AutoCompleteAdapter(this);
+ listView.setOnItemClickListener(this);
+ listView.setOnItemLongClickListener(this);
boolean IS_VOICE_SEARCH_INTENT = getIntent().getBooleanExtra(EXTRA_IS_WIDGET_VOICE, false);
if (IS_VOICE_SEARCH_INTENT) {
@@ -100,10 +100,20 @@ public class SearchActivity extends BaseActivity
}
}
+ public void activateDefaultAdapter() {
+ currentAdapter = defaultAdapter;
+ listView.setAdapter(currentAdapter);
+ }
+
+ public void activateAutoAdapter() {
+ currentAdapter = autoAdapter;
+ listView.setAdapter(currentAdapter);
+ }
+
@Override
public void addRecentSearches(List recentSearches) {
- mDefaultAdapter.addAll(recentSearches);
- mDefaultAdapter.notifyDataSetChanged();
+ defaultAdapter.addAll(recentSearches);
+ defaultAdapter.notifyDataSetChanged();
}
@Override
@@ -128,8 +138,8 @@ public class SearchActivity extends BaseActivity
searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
if (searchText != null) {
searchView.setQuery(searchText, false);
- mListView.setAdapter(mAutoAdapter);
- mAutoAdapter.getFilter().filter(searchText.toLowerCase());
+ activateAutoAdapter();
+ autoAdapter.getFilter().filter(searchText.toLowerCase());
}
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
@@ -140,10 +150,10 @@ public class SearchActivity extends BaseActivity
@Override
public boolean onQueryTextChange(String s) {
if (s.equals("")) {
- mListView.setAdapter(mDefaultAdapter);
+ activateDefaultAdapter();
} else {
- mListView.setAdapter(mAutoAdapter);
- mAutoAdapter.getFilter().filter(s.toLowerCase());
+ activateAutoAdapter();
+ autoAdapter.getFilter().filter(s.toLowerCase());
}
return true;
@@ -198,15 +208,7 @@ public class SearchActivity extends BaseActivity
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
- CharSequence text = ((TextView) view).getText();
- String title;
- if (text instanceof Spanned) {
- title = Html.toHtml((Spanned) text);
- // To remove the "ltr style information" from spanned text
- title = title.substring(title.indexOf(">") + 1, title.lastIndexOf("<"));
- } else {
- title = text.toString();
- }
+ String title = currentAdapter.getItem(position);
searchPresenter.saveSearch(title);
sendMessage(title);
}
@@ -242,8 +244,8 @@ public class SearchActivity extends BaseActivity
@Override
public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
- if (parent.getAdapter() == mDefaultAdapter) {
- String searched = mListView.getItemAtPosition(position).toString();
+ if (parent.getAdapter() == defaultAdapter) {
+ String searched = listView.getItemAtPosition(position).toString();
deleteSpecificSearchDialog(searched);
}
return true;
@@ -268,8 +270,8 @@ public class SearchActivity extends BaseActivity
}
private void resetAdapter() {
- mDefaultAdapter = getDefaultAdapter();
- mListView.setAdapter(mDefaultAdapter);
+ defaultAdapter = getDefaultAdapter();
+ activateDefaultAdapter();
searchPresenter.getRecentSearches();
}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/splash/SplashActivity.java b/app/src/main/java/org/kiwix/kiwixmobile/splash/SplashActivity.java
index 713195138..0071b6d35 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/splash/SplashActivity.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/splash/SplashActivity.java
@@ -34,7 +34,7 @@ public class SplashActivity extends BaseActivity {
super.onCreate(savedInstanceState);
if (!BuildConfig.DEBUG) {
- Context appContext = this;
+ Context appContext = getApplicationContext();
Thread.setDefaultUncaughtExceptionHandler((paramThread, paramThrowable) -> {
final Intent intent = new Intent(appContext, ErrorActivity.class);
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/utils/Constants.java b/app/src/main/java/org/kiwix/kiwixmobile/utils/Constants.java
index a952e3ba1..cb19e9e7d 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/utils/Constants.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/utils/Constants.java
@@ -17,6 +17,8 @@
*/
package org.kiwix.kiwixmobile.utils;
+import org.kiwix.kiwixmobile.BuildConfig;
+
public final class Constants {
public static final String TAG_KIWIX = "kiwix";
@@ -125,4 +127,8 @@ public final class Constants {
// Notification Channel Constants
public static final String ONGOING_DOWNLOAD_CHANNEL_ID = "ongoing_downloads_channel_id";
+ public static final String OLD_PROVIDER_DOMAIN = "org.kiwix.zim.base";
+
+ public static final String NEW_PROVIDER_DOMAIN = BuildConfig.APPLICATION_ID + ".zim.base";
+
}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/utils/LanguageUtils.java b/app/src/main/java/org/kiwix/kiwixmobile/utils/LanguageUtils.java
index a279fc5ac..7ff816575 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/utils/LanguageUtils.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/utils/LanguageUtils.java
@@ -107,10 +107,10 @@ public class LanguageUtils {
return mLocaleMap.get(iso3.toUpperCase());
}
- public static Locale getCurrentLocale(Context context){
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
+ public static Locale getCurrentLocale(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return context.getResources().getConfiguration().getLocales().get(0);
- } else{
+ } else {
//noinspection deprecation
return context.getResources().getConfiguration().locale;
}
@@ -151,6 +151,20 @@ public class LanguageUtils {
return "fonts/DejaVuSansCondensed.ttf";
}
+ public static String getResourceString(Context appContext, String str) {
+ String resourceName = str;
+ if (resourceName.contains("REPLACE_")) {
+ resourceName = resourceName.replace("REPLACE_", "");
+ }
+ int resourceId = appContext.getResources()
+ .getIdentifier(
+ resourceName,
+ "string",
+ appContext.getPackageName()
+ );
+ return appContext.getResources().getString(resourceId);
+ }
+
// Read the language codes, that are supported in this app from the locales.txt file
private void getLanguageCodesFromAssets() {
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/utils/UpdateUtils.java b/app/src/main/java/org/kiwix/kiwixmobile/utils/UpdateUtils.java
new file mode 100644
index 000000000..1201d96eb
--- /dev/null
+++ b/app/src/main/java/org/kiwix/kiwixmobile/utils/UpdateUtils.java
@@ -0,0 +1,10 @@
+package org.kiwix.kiwixmobile.utils;
+
+import static org.kiwix.kiwixmobile.utils.Constants.NEW_PROVIDER_DOMAIN;
+import static org.kiwix.kiwixmobile.utils.Constants.OLD_PROVIDER_DOMAIN;
+
+public class UpdateUtils {
+ public static String reformatProviderUrl(String url) {
+ return url.replace(OLD_PROVIDER_DOMAIN, NEW_PROVIDER_DOMAIN);
+ }
+}
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileUtils.java b/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileUtils.java
index e65fbb485..2807eee5d 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileUtils.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileUtils.java
@@ -27,6 +27,7 @@ import android.provider.DocumentsContract;
import android.util.Log;
import org.kiwix.kiwixmobile.BuildConfig;
+import org.kiwix.kiwixmobile.downloader.ChunkUtils;
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book;
import java.io.File;
@@ -61,8 +62,8 @@ public class FileUtils {
}
public static synchronized void deleteZimFile(String path) {
- if (path.substring(path.length() - 5).equals(".part")) {
- path = path.substring(0, path.length() - 5);
+ if (path.substring(path.length() - ChunkUtils.PART.length()).equals(ChunkUtils.PART)) {
+ path = path.substring(0, path.length() - ChunkUtils.PART.length());
}
Log.i("kiwix", "Deleting file: " + path);
File file = new File(path);
@@ -86,10 +87,16 @@ public class FileUtils {
}
private static synchronized boolean deleteZimFileParts(String path) {
- File file = new File(path + ".part");
+ File file = new File(path + ChunkUtils.PART);
if (file.exists()) {
file.delete();
return true;
+ } else {
+ File singlePart = new File(path + ".part");
+ if (singlePart.exists()) {
+ singlePart.delete();
+ return true;
+ }
}
return false;
}
@@ -206,15 +213,16 @@ public class FileUtils {
stream.read(buffer);
stream.close();
content = new String(buffer);
- } catch (IOException ignored) { }
+ } catch (IOException ignored) {
+ }
return readCsv(content);
}
public static List getAllZimParts(Book book) {
List files = new ArrayList<>();
- if(book.file.getPath().endsWith(".zim") || book.file.getPath().endsWith(".zim.part")) {
- if(book.file.exists()) {
+ if (book.file.getPath().endsWith(".zim") || book.file.getPath().endsWith(".zim.part")) {
+ if (book.file.exists()) {
files.add(book.file);
} else {
files.add(new File(book.file + ".part"));
@@ -222,12 +230,12 @@ public class FileUtils {
return files;
}
String path = book.file.getPath();
- for(char alphabetFirst = 'a'; alphabetFirst <= 'z'; alphabetFirst++) {
- for(char alphabetSecond = 'a'; alphabetSecond <= 'z'; alphabetSecond++) {
+ for (char alphabetFirst = 'a'; alphabetFirst <= 'z'; alphabetFirst++) {
+ for (char alphabetSecond = 'a'; alphabetSecond <= 'z'; alphabetSecond++) {
path = path.substring(0, path.length() - 2) + alphabetFirst + alphabetSecond;
- if(new File(path).exists()) {
+ if (new File(path).exists()) {
files.add(new File(path));
- } else if(new File(path + ".part").exists()) {
+ } else if (new File(path + ".part").exists()) {
files.add(new File(path + ".part"));
} else {
return files;
@@ -267,7 +275,7 @@ public class FileUtils {
return false;
}
- public static String getFileName (String fileName) {
+ public static String getFileName(String fileName) {
if (new File(fileName).exists()) {
return fileName;
} else if (new File(fileName + ".part").exists()) {
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/ZimFileSelectFragment.java b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/ZimFileSelectFragment.java
index e90816d04..3f2d0ad68 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/ZimFileSelectFragment.java
+++ b/app/src/main/java/org/kiwix/kiwixmobile/zim_manager/fileselect_view/ZimFileSelectFragment.java
@@ -163,11 +163,11 @@ public class ZimFileSelectFragment extends BaseFragment
public void checkPermissions() {
if (ContextCompat.checkSelfPermission(zimManageActivity,
- Manifest.permission.READ_EXTERNAL_STORAGE)
+ Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED && Build.VERSION.SDK_INT > 18) {
Toast.makeText(super.getActivity(), getResources().getString(R.string.request_storage), Toast.LENGTH_LONG)
.show();
- requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
+ requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_STORAGE_PERMISSION);
} else {
getFiles();
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index f3038bc07..8d6047582 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -44,6 +44,7 @@
- @color/primary_light
- @color/primary_light
- @color/primary_light
+ - @style/AppTheme.Dialog.Night
- @color/accent
@@ -79,10 +80,12 @@