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 @@