mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-08 06:42:21 -04:00
Merge pull request #850 from kiwix/abdulwd/merge
Merge master branch with 3.0
This commit is contained in:
commit
40e74aec1f
45
.github/ISSUE_TEMPLATE.md
vendored
45
.github/ISSUE_TEMPLATE.md
vendored
@ -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.
|
|
||||||
|
|
||||||
|
|
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Checklist for reporting a bug
|
||||||
|
- Check the issue tracker. The issue you have may have already been reported.
|
||||||
|
- Ensure you have tested the latest developers version.
|
||||||
|
-->
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
<!-- A clear and concise description of what the bug is. -->
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
<!-- A clear and concise description of what you expected to happen. -->
|
||||||
|
|
||||||
|
**Steps to reproduce the behavior:**
|
||||||
|
1.
|
||||||
|
<!--
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
-->
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
<!-- If applicable, add screenshots to help explain your problem otherwise delete this heading. -->
|
||||||
|
|
||||||
|
**Environment**
|
||||||
|
- Version of Kiwix Android :
|
||||||
|
- Device :
|
||||||
|
- OS version :
|
||||||
|
|
||||||
|
**Logs**
|
||||||
|
<!-- If applicable, add logs to help the developers in identifying your problem otherwise delete this heading. -->
|
23
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
23
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Checklist for requesting a feature:
|
||||||
|
- Check the issue tracker. The feature you are requesting may have already been requested.
|
||||||
|
- Check if the feature does not exists on the latest developers version.
|
||||||
|
-->
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
<!-- A clear and concise description of what the problem is. Example: I'm always frustrated when [...] -->
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
<!-- A clear and concise description of what you want to happen. -->
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
<!-- A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
If not applicable delete this heading. -->
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
<!-- Add any other context or screenshots about the feature request here.
|
||||||
|
If not applicable delete this heading. -->
|
31
.github/ISSUE_TEMPLATE/test_request.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE/test_request.md
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: Request Tests
|
||||||
|
about: Identify code liable to break and create tests to prevent software regression due to code changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Checklist for reporting a bug
|
||||||
|
- Check the issue tracker. The issue you have may have already been reported.
|
||||||
|
- Ensure that you are using the latest developers version.
|
||||||
|
- Make sure that the tests are not for any other framework libraries that are being used in the code.
|
||||||
|
- Prefer code that seems to get changed by different developers and accessed by a lot of other modules.
|
||||||
|
-->
|
||||||
|
|
||||||
|
**Type of Test**
|
||||||
|
<!-- Unit Test or UI Test -->
|
||||||
|
* [ ] Unit Test
|
||||||
|
* [ ] UI Test
|
||||||
|
|
||||||
|
**Particular area and files to be tested**
|
||||||
|
<!--
|
||||||
|
In case of Unit Tests, mention the names of the files or modules to be tested.
|
||||||
|
In case of UI Tests, mention the names of the activities to be tested.
|
||||||
|
-->
|
||||||
|
|
||||||
|
**Current Status of the tests**
|
||||||
|
<!-- Are there any tests included for this particular area, which need improvement, or has this are never been tested at all?
|
||||||
|
(You can see the tests that we are currently using in the "androidTest", and "androidTestKiwix" folders in the "app/src" folder) -->
|
||||||
|
|
||||||
|
**Particular Behaviour to be tested**
|
||||||
|
<!-- Give a brief description of the particular cases which need to be tested.
|
||||||
|
(For example: test whether data is saved in the database on clicking a particular button, or test whether the default language is preselected, etc) -->
|
@ -1,4 +1,4 @@
|
|||||||
2.3
|
2.4
|
||||||
FIX: External SD card problems
|
FIX: External SD card problems
|
||||||
FIX: Some UI translation
|
FIX: Some UI translation
|
||||||
FIX: Download manager process sporadic problems
|
FIX: Download manager process sporadic problems
|
||||||
|
@ -76,7 +76,7 @@ public class BasicTest {
|
|||||||
openDrawerWithGravity(R.id.drawer_layout, Gravity.RIGHT);
|
openDrawerWithGravity(R.id.drawer_layout, Gravity.RIGHT);
|
||||||
assertDrawerIsOpenWithGravity(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);
|
closeDrawerWithGravity(R.id.drawer_layout, Gravity.RIGHT);
|
||||||
assertDrawerIsClosedWithGravity(R.id.drawer_layout, Gravity.RIGHT);*/
|
assertDrawerIsClosedWithGravity(R.id.drawer_layout, Gravity.RIGHT);*/
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<title>Home</title>
|
<title>REPLACE_menu_home</title>
|
||||||
</head>
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 style="display:none;">REPLACE_menu_home</h1>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -23,6 +23,7 @@ import android.support.annotation.Nullable;
|
|||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
|
||||||
import org.kiwix.kiwixmobile.R;
|
import org.kiwix.kiwixmobile.R;
|
||||||
|
import org.kiwix.kiwixmobile.utils.LanguageUtils;
|
||||||
import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil;
|
import org.kiwix.kiwixmobile.utils.SharedPreferenceUtil;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -42,6 +43,7 @@ public abstract class BaseActivity extends AppCompatActivity {
|
|||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
AndroidInjection.inject(this);
|
AndroidInjection.inject(this);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
LanguageUtils.handleLocaleChange(this, sharedPreferenceUtil);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -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.NetworkLanguageDatabaseEntity;
|
||||||
import org.kiwix.kiwixmobile.data.local.entity.RecentSearch;
|
import org.kiwix.kiwixmobile.data.local.entity.RecentSearch;
|
||||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
|
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
|
||||||
|
import org.kiwix.kiwixmobile.utils.UpdateUtils;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -52,7 +53,7 @@ import static org.kiwix.kiwixmobile.utils.Constants.TAG_KIWIX;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class KiwixDatabase extends SquidDatabase {
|
public class KiwixDatabase extends SquidDatabase {
|
||||||
|
|
||||||
private static final int VERSION = 16;
|
private static final int VERSION = 17;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -125,6 +126,8 @@ public class KiwixDatabase extends SquidDatabase {
|
|||||||
tryAddColumn(Bookmark.ZIM_FILE_PATH);
|
tryAddColumn(Bookmark.ZIM_FILE_PATH);
|
||||||
tryAddColumn(Bookmark.FAVICON);
|
tryAddColumn(Bookmark.FAVICON);
|
||||||
migrateBookmarksVersion16();
|
migrateBookmarksVersion16();
|
||||||
|
case 16:
|
||||||
|
new BookmarksDao(this).processBookmark(UpdateUtils::reformatProviderUrl);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.data.local.dao;
|
|||||||
|
|
||||||
import com.yahoo.squidb.data.SquidCursor;
|
import com.yahoo.squidb.data.SquidCursor;
|
||||||
import com.yahoo.squidb.sql.Query;
|
import com.yahoo.squidb.sql.Query;
|
||||||
|
import com.yahoo.squidb.sql.Update;
|
||||||
|
|
||||||
import org.kiwix.kiwixmobile.data.ZimContentProvider;
|
import org.kiwix.kiwixmobile.data.ZimContentProvider;
|
||||||
import org.kiwix.kiwixmobile.data.local.KiwixDatabase;
|
import org.kiwix.kiwixmobile.data.local.KiwixDatabase;
|
||||||
@ -107,4 +108,23 @@ public class BookmarksDao {
|
|||||||
kiwixDatabase.deleteWhere(Bookmark.class, Bookmark.BOOKMARK_URL.eq(bookmark.getBookmarkUrl())
|
kiwixDatabase.deleteWhere(Bookmark.class, Bookmark.BOOKMARK_URL.eq(bookmark.getBookmarkUrl())
|
||||||
.and(Bookmark.ZIM_ID.eq(bookmark.getZimId())));
|
.and(Bookmark.ZIM_ID.eq(bookmark.getZimId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void processBookmark(StringOperation operation) {
|
||||||
|
try (SquidCursor<Bookmark> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public class ChunkUtils {
|
|||||||
|
|
||||||
public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
|
public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
|
||||||
public static final String ZIM_EXTENSION = ".zim";
|
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 final long CHUNK_SIZE = 1024L * 1024L * 1024L * 2L;
|
||||||
|
|
||||||
public static List<Chunk> getChunks(String url, long contentLength, int notificationID) {
|
public static List<Chunk> getChunks(String url, long contentLength, int notificationID) {
|
||||||
@ -63,7 +63,7 @@ public class ChunkUtils {
|
|||||||
|
|
||||||
private static String[] getZimChunkFileNames(String fileName, int count) {
|
private static String[] getZimChunkFileNames(String fileName, int count) {
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
return new String[] { fileName + PART};
|
return new String[]{fileName + PART};
|
||||||
}
|
}
|
||||||
int position = fileName.lastIndexOf(".");
|
int position = fileName.lastIndexOf(".");
|
||||||
String baseName = position > 0 ? fileName.substring(0, position) : fileName;
|
String baseName = position > 0 ? fileName.substring(0, position) : fileName;
|
||||||
|
@ -71,6 +71,9 @@ import okhttp3.Request;
|
|||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
import okio.BufferedSource;
|
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_BOOK;
|
||||||
import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_LIBRARY;
|
import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_LIBRARY;
|
||||||
import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_NOTIFICATION_ID;
|
import static org.kiwix.kiwixmobile.utils.Constants.EXTRA_NOTIFICATION_ID;
|
||||||
@ -139,8 +142,7 @@ public class DownloadService extends Service {
|
|||||||
if (intent == null) {
|
if (intent == null) {
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
}
|
}
|
||||||
String log = intent.getAction();
|
String log = intent.getAction() + " : ";
|
||||||
log += " : ";
|
|
||||||
if (intent.hasExtra(NOTIFICATION_ID)) {
|
if (intent.hasExtra(NOTIFICATION_ID)) {
|
||||||
log += intent.getIntExtra(NOTIFICATION_ID, -3);
|
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));
|
notification.get(notificationID).setContentText(getString(R.string.zim_file_downloaded));
|
||||||
final Intent target = new Intent(DownloadService.this, MainActivity.class);
|
final Intent target = new Intent(DownloadService.this, MainActivity.class);
|
||||||
target.putExtra(EXTRA_ZIM_FILE, KIWIX_ROOT + StorageUtils.getFileNameFromUrl(book.getUrl()));
|
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);
|
target.putExtra(EXTRA_NOTIFICATION_ID, notificationID);
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity
|
PendingIntent pendingIntent = PendingIntent.getActivity
|
||||||
(getBaseContext(), 0,
|
(getBaseContext(), 0,
|
||||||
@ -453,7 +484,7 @@ public class DownloadService extends Service {
|
|||||||
// Create chunk file
|
// Create chunk file
|
||||||
File file = new File(KIWIX_ROOT, chunk.getFileName());
|
File file = new File(KIWIX_ROOT, chunk.getFileName());
|
||||||
file.getParentFile().mkdirs();
|
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]);
|
long downloaded = Long.parseLong(chunk.getRangeHeader().split("-")[0]);
|
||||||
if (fullFile.exists() && fullFile.length() == chunk.getSize()) {
|
if (fullFile.exists() && fullFile.length() == chunk.getSize()) {
|
||||||
@ -535,7 +566,8 @@ public class DownloadService extends Service {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MainActivity.wifiOnly && !NetworkUtils.isWiFi(getApplicationContext())) {
|
if (MainActivity.wifiOnly && !NetworkUtils.isWiFi(getApplicationContext()) ||
|
||||||
|
!NetworkUtils.isNetworkAvailable(getApplicationContext())) {
|
||||||
pauseDownload(chunk.getNotificationID());
|
pauseDownload(chunk.getNotificationID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,16 +626,16 @@ public class DownloadService extends Service {
|
|||||||
if (downloadStatus.get(chunk.getNotificationID()) == CANCEL) {
|
if (downloadStatus.get(chunk.getNotificationID()) == CANCEL) {
|
||||||
String path = file.getPath();
|
String path = file.getPath();
|
||||||
Log.i(KIWIX_TAG, "Download Cancelled, deleting file: " + path);
|
Log.i(KIWIX_TAG, "Download Cancelled, deleting file: " + path);
|
||||||
if (path.substring(path.length() - 8).equals("zim.part")) {
|
if (path.substring(path.length() - (ZIM_EXTENSION + PART).length()).equals(ZIM_EXTENSION + PART)) {
|
||||||
path = path.substring(0, path.length() - 5);
|
path = path.substring(0, path.length() - PART.length() + 1);
|
||||||
FileUtils.deleteZimFile(path);
|
FileUtils.deleteZimFile(path);
|
||||||
} else {
|
} else {
|
||||||
path = path.substring(0, path.length() - 7) + "aa";
|
path = path.substring(0, path.length() - (ZIM_EXTENSION + PART).length() + 2) + "aa";
|
||||||
FileUtils.deleteZimFile(path);
|
FileUtils.deleteZimFile(path);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.i(KIWIX_TAG, "Download completed, renaming file ([" + file.getPath() + "] -> .zim)");
|
Log.i(KIWIX_TAG, "Download completed, renaming file ([" + file.getPath() + "] -> .zim.part)");
|
||||||
file.renameTo(new File(file.getPath().replace(".part", "")));
|
file.renameTo(new File(file.getPath().replaceAll(".part$", "")));
|
||||||
}
|
}
|
||||||
// Mark chunk status as downloaded
|
// Mark chunk status as downloaded
|
||||||
chunk.isDownloaded = true;
|
chunk.isDownloaded = true;
|
||||||
@ -627,6 +659,7 @@ public class DownloadService extends Service {
|
|||||||
NotificationChannel ongoingDownloadsChannel = new NotificationChannel(
|
NotificationChannel ongoingDownloadsChannel = new NotificationChannel(
|
||||||
Constants.ONGOING_DOWNLOAD_CHANNEL_ID, name, importance);
|
Constants.ONGOING_DOWNLOAD_CHANNEL_ID, name, importance);
|
||||||
ongoingDownloadsChannel.setDescription(description);
|
ongoingDownloadsChannel.setDescription(description);
|
||||||
|
ongoingDownloadsChannel.setSound(null, null);
|
||||||
NotificationManager notificationManager = (NotificationManager) getSystemService(
|
NotificationManager notificationManager = (NotificationManager) getSystemService(
|
||||||
NOTIFICATION_SERVICE);
|
NOTIFICATION_SERVICE);
|
||||||
notificationManager.createNotificationChannel(ongoingDownloadsChannel);
|
notificationManager.createNotificationChannel(ongoingDownloadsChannel);
|
||||||
|
@ -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_CURRENT_TAB;
|
||||||
import static org.kiwix.kiwixmobile.utils.Constants.TAG_FILE_SEARCHED;
|
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.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.StyleUtils.dialogStyle;
|
||||||
|
import static org.kiwix.kiwixmobile.utils.UpdateUtils.reformatProviderUrl;
|
||||||
|
|
||||||
public class MainActivity extends BaseActivity implements WebViewCallback,
|
public class MainActivity extends BaseActivity implements WebViewCallback,
|
||||||
MainContract.View, BooksAdapter.OnItemClickListener {
|
MainContract.View, BooksAdapter.OnItemClickListener {
|
||||||
@ -321,6 +323,7 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
presenter.attachView(this);
|
presenter.attachView(this);
|
||||||
|
new WebView(this).destroy(); // Workaround for buggy webViews see #710
|
||||||
wifiOnly = sharedPreferenceUtil.getPrefWifiOnly();
|
wifiOnly = sharedPreferenceUtil.getPrefWifiOnly();
|
||||||
nightMode = sharedPreferenceUtil.nightMode();
|
nightMode = sharedPreferenceUtil.nightMode();
|
||||||
handleLocaleCheck();
|
handleLocaleCheck();
|
||||||
@ -346,25 +349,8 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
|
|||||||
|
|
||||||
tableDrawerRight.setLayoutManager(new LinearLayoutManager(this));
|
tableDrawerRight.setLayoutManager(new LinearLayoutManager(this));
|
||||||
|
|
||||||
TableDrawerAdapter tableDrawerAdapter = new TableDrawerAdapter();
|
TableDrawerAdapter tableDrawerAdapter = setupTableDrawerAdapter();
|
||||||
tableDrawerRight.setAdapter(tableDrawerAdapter);
|
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();
|
tableDrawerAdapter.notifyDataSetChanged();
|
||||||
|
|
||||||
tabsAdapter.setTabClickListener(new TabsAdapter.TabClickListener() {
|
tabsAdapter.setTabClickListener(new TabsAdapter.TabClickListener() {
|
||||||
@ -391,8 +377,17 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
|
|||||||
documentParser = new DocumentParser(new DocumentParser.SectionsListener() {
|
documentParser = new DocumentParser(new DocumentParser.SectionsListener() {
|
||||||
@Override
|
@Override
|
||||||
public void sectionsLoaded(String title, List<DocumentSection> sections) {
|
public void sectionsLoaded(String title, List<DocumentSection> sections) {
|
||||||
|
for (DocumentSection section : sections) {
|
||||||
|
if (section.title.contains("REPLACE_")) {
|
||||||
|
section.title = getResourceString(getApplicationContext(), section.title);
|
||||||
|
}
|
||||||
|
}
|
||||||
documentSections.addAll(sections);
|
documentSections.addAll(sections);
|
||||||
tableDrawerAdapter.setTitle(title);
|
if (title.contains("REPLACE_")) {
|
||||||
|
tableDrawerAdapter.setTitle(getResourceString(getApplicationContext(), title));
|
||||||
|
} else {
|
||||||
|
tableDrawerAdapter.setTitle(title);
|
||||||
|
}
|
||||||
tableDrawerAdapter.setSections(documentSections);
|
tableDrawerAdapter.setSections(documentSections);
|
||||||
tableDrawerAdapter.notifyDataSetChanged();
|
tableDrawerAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
@ -443,6 +438,26 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
|
|||||||
new ItemTouchHelper(tabCallback).attachToRecyclerView(tabRecyclerView);
|
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() {
|
private void showTabSwitcher() {
|
||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
actionBar.setHomeAsUpIndicator(ContextCompat.getDrawable(this, R.drawable.ic_round_add_white_36dp));
|
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 (webViewList.size() == 0) return newTab();
|
||||||
if (currentWebViewIndex < webViewList.size()) {
|
if (currentWebViewIndex < webViewList.size()) {
|
||||||
return webViewList.get(currentWebViewIndex);
|
return webViewList.get(currentWebViewIndex);
|
||||||
@ -1191,18 +1206,19 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
|
|||||||
intent.setAction("");
|
intent.setAction("");
|
||||||
goToSearch(true);
|
goToSearch(true);
|
||||||
break;
|
break;
|
||||||
case Intent.ACTION_VIEW: {
|
case Intent.ACTION_VIEW:
|
||||||
final String zimFile = ZimContentProvider.getZimFile();
|
if (intent.getType() == null || !intent.getType().equals("application/octet-stream")) {
|
||||||
saveTabStates();
|
final String zimFile = ZimContentProvider.getZimFile();
|
||||||
Intent i = new Intent(MainActivity.this, SearchActivity.class);
|
saveTabStates();
|
||||||
i.putExtra(EXTRA_ZIM_FILE, zimFile);
|
Intent i = new Intent(MainActivity.this, SearchActivity.class);
|
||||||
if (intent.getData() != null) {
|
i.putExtra(EXTRA_ZIM_FILE, zimFile);
|
||||||
i.putExtra(EXTRA_SEARCH, intent.getData().getLastPathSegment());
|
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;
|
break;
|
||||||
}
|
|
||||||
case NEW_TAB:
|
case NEW_TAB:
|
||||||
newTab(HOME_URL);
|
newTab(HOME_URL);
|
||||||
break;
|
break;
|
||||||
@ -1602,11 +1618,11 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
|
|||||||
JSONArray urls = new JSONArray(zimArticles);
|
JSONArray urls = new JSONArray(zimArticles);
|
||||||
JSONArray positions = new JSONArray(zimPositions);
|
JSONArray positions = new JSONArray(zimPositions);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
getCurrentWebView().loadUrl(urls.getString(i));
|
getCurrentWebView().loadUrl(reformatProviderUrl(urls.getString(i)));
|
||||||
getCurrentWebView().setScrollY(positions.getInt(i));
|
getCurrentWebView().setScrollY(positions.getInt(i));
|
||||||
i++;
|
i++;
|
||||||
for (; i < urls.length(); i++) {
|
for (; i < urls.length(); i++) {
|
||||||
newTab(urls.getString(i));
|
newTab(reformatProviderUrl(urls.getString(i)));
|
||||||
getCurrentWebView().setScrollY(positions.getInt(i));
|
getCurrentWebView().setScrollY(positions.getInt(i));
|
||||||
}
|
}
|
||||||
selectTab(currentTab);
|
selectTab(currentTab);
|
||||||
|
@ -20,6 +20,7 @@ package org.kiwix.kiwixmobile.main;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -45,7 +46,7 @@ public class TableDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
|
|
||||||
private int selectedPosition = 0;
|
private int selectedPosition = 0;
|
||||||
|
|
||||||
public TableDrawerAdapter() {
|
TableDrawerAdapter() {
|
||||||
sections = new ArrayList<>();
|
sections = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,8 +55,9 @@ public class TableDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
int resource = R.layout.section_list;
|
int resource = R.layout.section_list;
|
||||||
Context context = parent.getContext();
|
Context context = parent.getContext();
|
||||||
View v = LayoutInflater.from(context).inflate(resource, parent, false);
|
View v = LayoutInflater.from(context).inflate(resource, parent, false);
|
||||||
@ -72,7 +74,7 @@ public class TableDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||||
ViewHolder vh = (ViewHolder) holder;
|
ViewHolder vh = (ViewHolder) holder;
|
||||||
|
|
||||||
Context context = holder.itemView.getContext();
|
Context context = holder.itemView.getContext();
|
||||||
@ -85,6 +87,9 @@ public class TableDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
vh.title.setText(title);
|
vh.title.setText(title);
|
||||||
} else {
|
} else {
|
||||||
String empty = context.getString(R.string.no_section_info);
|
String empty = context.getString(R.string.no_section_info);
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
empty = ((MainActivity) context).getCurrentWebView().getTitle();
|
||||||
|
}
|
||||||
vh.title.setText(empty);
|
vh.title.setText(empty);
|
||||||
}
|
}
|
||||||
vh.itemView.setOnClickListener(v -> {
|
vh.itemView.setOnClickListener(v -> {
|
||||||
@ -152,14 +157,14 @@ public class TableDrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
|
|
||||||
public static class HeaderViewHolder extends ViewHolder {
|
public static class HeaderViewHolder extends ViewHolder {
|
||||||
|
|
||||||
public HeaderViewHolder(View v) {
|
HeaderViewHolder(View v) {
|
||||||
super(v);
|
super(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SectionViewHolder extends ViewHolder {
|
public static class SectionViewHolder extends ViewHolder {
|
||||||
|
|
||||||
public SectionViewHolder(View v) {
|
SectionViewHolder(View v) {
|
||||||
super(v);
|
super(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import static org.kiwix.kiwixmobile.utils.DimenUtils.getToolbarHeight;
|
|||||||
import static org.kiwix.kiwixmobile.utils.DimenUtils.getWindowHeight;
|
import static org.kiwix.kiwixmobile.utils.DimenUtils.getWindowHeight;
|
||||||
import static org.kiwix.kiwixmobile.utils.DimenUtils.getWindowWidth;
|
import static org.kiwix.kiwixmobile.utils.DimenUtils.getWindowWidth;
|
||||||
import static org.kiwix.kiwixmobile.utils.ImageUtils.getBitmapFromView;
|
import static org.kiwix.kiwixmobile.utils.ImageUtils.getBitmapFromView;
|
||||||
|
import static org.kiwix.kiwixmobile.utils.LanguageUtils.getResourceString;
|
||||||
import static org.kiwix.kiwixmobile.utils.StyleUtils.fromHtml;
|
import static org.kiwix.kiwixmobile.utils.StyleUtils.fromHtml;
|
||||||
|
|
||||||
public class TabsAdapter extends RecyclerView.Adapter<TabsAdapter.ViewHolder> {
|
public class TabsAdapter extends RecyclerView.Adapter<TabsAdapter.ViewHolder> {
|
||||||
@ -113,7 +114,11 @@ public class TabsAdapter extends RecyclerView.Adapter<TabsAdapter.ViewHolder> {
|
|||||||
if (webView.getParent() != null) {
|
if (webView.getParent() != null) {
|
||||||
((ViewGroup) webView.getParent()).removeView(webView);
|
((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.close.setOnClickListener(v -> listener.onCloseTab(v, holder.getAdapterPosition()));
|
||||||
holder.content.setImageBitmap(getBitmapFromView(webView));
|
holder.content.setImageBitmap(getBitmapFromView(webView));
|
||||||
holder.content.setOnClickListener(v -> {
|
holder.content.setOnClickListener(v -> {
|
||||||
|
@ -29,7 +29,6 @@ import android.support.v7.app.AlertDialog;
|
|||||||
import android.support.v7.widget.SearchView;
|
import android.support.v7.widget.SearchView;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.Spanned;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@ -63,9 +62,10 @@ public class SearchActivity extends BaseActivity
|
|||||||
public static final String EXTRA_SEARCH_IN_TEXT = "bool_searchintext";
|
public static final String EXTRA_SEARCH_IN_TEXT = "bool_searchintext";
|
||||||
|
|
||||||
private final int REQ_CODE_SPEECH_INPUT = 100;
|
private final int REQ_CODE_SPEECH_INPUT = 100;
|
||||||
private ListView mListView;
|
private ListView listView;
|
||||||
private AutoCompleteAdapter mAutoAdapter;
|
private ArrayAdapter<String> currentAdapter;
|
||||||
private ArrayAdapter<String> mDefaultAdapter;
|
private AutoCompleteAdapter autoAdapter;
|
||||||
|
private ArrayAdapter<String> defaultAdapter;
|
||||||
private SearchView searchView;
|
private SearchView searchView;
|
||||||
private String searchText;
|
private String searchText;
|
||||||
|
|
||||||
@ -85,14 +85,14 @@ public class SearchActivity extends BaseActivity
|
|||||||
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_back);
|
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_back);
|
||||||
getSupportActionBar().setHomeButtonEnabled(true);
|
getSupportActionBar().setHomeButtonEnabled(true);
|
||||||
searchPresenter.attachView(this);
|
searchPresenter.attachView(this);
|
||||||
mListView = findViewById(R.id.search_list);
|
listView = findViewById(R.id.search_list);
|
||||||
mDefaultAdapter = getDefaultAdapter();
|
defaultAdapter = getDefaultAdapter();
|
||||||
searchPresenter.getRecentSearches();
|
searchPresenter.getRecentSearches();
|
||||||
mListView.setAdapter(mDefaultAdapter);
|
activateDefaultAdapter();
|
||||||
|
|
||||||
mAutoAdapter = new AutoCompleteAdapter(this);
|
autoAdapter = new AutoCompleteAdapter(this);
|
||||||
mListView.setOnItemClickListener(this);
|
listView.setOnItemClickListener(this);
|
||||||
mListView.setOnItemLongClickListener(this);
|
listView.setOnItemLongClickListener(this);
|
||||||
|
|
||||||
boolean IS_VOICE_SEARCH_INTENT = getIntent().getBooleanExtra(EXTRA_IS_WIDGET_VOICE, false);
|
boolean IS_VOICE_SEARCH_INTENT = getIntent().getBooleanExtra(EXTRA_IS_WIDGET_VOICE, false);
|
||||||
if (IS_VOICE_SEARCH_INTENT) {
|
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
|
@Override
|
||||||
public void addRecentSearches(List<String> recentSearches) {
|
public void addRecentSearches(List<String> recentSearches) {
|
||||||
mDefaultAdapter.addAll(recentSearches);
|
defaultAdapter.addAll(recentSearches);
|
||||||
mDefaultAdapter.notifyDataSetChanged();
|
defaultAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -128,8 +138,8 @@ public class SearchActivity extends BaseActivity
|
|||||||
searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
|
||||||
if (searchText != null) {
|
if (searchText != null) {
|
||||||
searchView.setQuery(searchText, false);
|
searchView.setQuery(searchText, false);
|
||||||
mListView.setAdapter(mAutoAdapter);
|
activateAutoAdapter();
|
||||||
mAutoAdapter.getFilter().filter(searchText.toLowerCase());
|
autoAdapter.getFilter().filter(searchText.toLowerCase());
|
||||||
}
|
}
|
||||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -140,10 +150,10 @@ public class SearchActivity extends BaseActivity
|
|||||||
@Override
|
@Override
|
||||||
public boolean onQueryTextChange(String s) {
|
public boolean onQueryTextChange(String s) {
|
||||||
if (s.equals("")) {
|
if (s.equals("")) {
|
||||||
mListView.setAdapter(mDefaultAdapter);
|
activateDefaultAdapter();
|
||||||
} else {
|
} else {
|
||||||
mListView.setAdapter(mAutoAdapter);
|
activateAutoAdapter();
|
||||||
mAutoAdapter.getFilter().filter(s.toLowerCase());
|
autoAdapter.getFilter().filter(s.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -198,15 +208,7 @@ public class SearchActivity extends BaseActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
CharSequence text = ((TextView) view).getText();
|
String title = currentAdapter.getItem(position);
|
||||||
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();
|
|
||||||
}
|
|
||||||
searchPresenter.saveSearch(title);
|
searchPresenter.saveSearch(title);
|
||||||
sendMessage(title);
|
sendMessage(title);
|
||||||
}
|
}
|
||||||
@ -242,8 +244,8 @@ public class SearchActivity extends BaseActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
if (parent.getAdapter() == mDefaultAdapter) {
|
if (parent.getAdapter() == defaultAdapter) {
|
||||||
String searched = mListView.getItemAtPosition(position).toString();
|
String searched = listView.getItemAtPosition(position).toString();
|
||||||
deleteSpecificSearchDialog(searched);
|
deleteSpecificSearchDialog(searched);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -268,8 +270,8 @@ public class SearchActivity extends BaseActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resetAdapter() {
|
private void resetAdapter() {
|
||||||
mDefaultAdapter = getDefaultAdapter();
|
defaultAdapter = getDefaultAdapter();
|
||||||
mListView.setAdapter(mDefaultAdapter);
|
activateDefaultAdapter();
|
||||||
searchPresenter.getRecentSearches();
|
searchPresenter.getRecentSearches();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public class SplashActivity extends BaseActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
if (!BuildConfig.DEBUG) {
|
if (!BuildConfig.DEBUG) {
|
||||||
Context appContext = this;
|
Context appContext = getApplicationContext();
|
||||||
Thread.setDefaultUncaughtExceptionHandler((paramThread, paramThrowable) -> {
|
Thread.setDefaultUncaughtExceptionHandler((paramThread, paramThrowable) -> {
|
||||||
|
|
||||||
final Intent intent = new Intent(appContext, ErrorActivity.class);
|
final Intent intent = new Intent(appContext, ErrorActivity.class);
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.kiwix.kiwixmobile.utils;
|
package org.kiwix.kiwixmobile.utils;
|
||||||
|
|
||||||
|
import org.kiwix.kiwixmobile.BuildConfig;
|
||||||
|
|
||||||
public final class Constants {
|
public final class Constants {
|
||||||
|
|
||||||
public static final String TAG_KIWIX = "kiwix";
|
public static final String TAG_KIWIX = "kiwix";
|
||||||
@ -125,4 +127,8 @@ public final class Constants {
|
|||||||
// Notification Channel Constants
|
// Notification Channel Constants
|
||||||
public static final String ONGOING_DOWNLOAD_CHANNEL_ID = "ongoing_downloads_channel_id";
|
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";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -107,10 +107,10 @@ public class LanguageUtils {
|
|||||||
return mLocaleMap.get(iso3.toUpperCase());
|
return mLocaleMap.get(iso3.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Locale getCurrentLocale(Context context){
|
public static Locale getCurrentLocale(Context context) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
return context.getResources().getConfiguration().getLocales().get(0);
|
return context.getResources().getConfiguration().getLocales().get(0);
|
||||||
} else{
|
} else {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
return context.getResources().getConfiguration().locale;
|
return context.getResources().getConfiguration().locale;
|
||||||
}
|
}
|
||||||
@ -151,6 +151,20 @@ public class LanguageUtils {
|
|||||||
return "fonts/DejaVuSansCondensed.ttf";
|
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
|
// Read the language codes, that are supported in this app from the locales.txt file
|
||||||
private void getLanguageCodesFromAssets() {
|
private void getLanguageCodesFromAssets() {
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,7 @@ import android.provider.DocumentsContract;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import org.kiwix.kiwixmobile.BuildConfig;
|
import org.kiwix.kiwixmobile.BuildConfig;
|
||||||
|
import org.kiwix.kiwixmobile.downloader.ChunkUtils;
|
||||||
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book;
|
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -61,8 +62,8 @@ public class FileUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void deleteZimFile(String path) {
|
public static synchronized void deleteZimFile(String path) {
|
||||||
if (path.substring(path.length() - 5).equals(".part")) {
|
if (path.substring(path.length() - ChunkUtils.PART.length()).equals(ChunkUtils.PART)) {
|
||||||
path = path.substring(0, path.length() - 5);
|
path = path.substring(0, path.length() - ChunkUtils.PART.length());
|
||||||
}
|
}
|
||||||
Log.i("kiwix", "Deleting file: " + path);
|
Log.i("kiwix", "Deleting file: " + path);
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
@ -86,10 +87,16 @@ public class FileUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static synchronized boolean deleteZimFileParts(String path) {
|
private static synchronized boolean deleteZimFileParts(String path) {
|
||||||
File file = new File(path + ".part");
|
File file = new File(path + ChunkUtils.PART);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
file.delete();
|
file.delete();
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
File singlePart = new File(path + ".part");
|
||||||
|
if (singlePart.exists()) {
|
||||||
|
singlePart.delete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -206,15 +213,16 @@ public class FileUtils {
|
|||||||
stream.read(buffer);
|
stream.read(buffer);
|
||||||
stream.close();
|
stream.close();
|
||||||
content = new String(buffer);
|
content = new String(buffer);
|
||||||
} catch (IOException ignored) { }
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
return readCsv(content);
|
return readCsv(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<File> getAllZimParts(Book book) {
|
public static List<File> getAllZimParts(Book book) {
|
||||||
List<File> files = new ArrayList<>();
|
List<File> files = new ArrayList<>();
|
||||||
if(book.file.getPath().endsWith(".zim") || book.file.getPath().endsWith(".zim.part")) {
|
if (book.file.getPath().endsWith(".zim") || book.file.getPath().endsWith(".zim.part")) {
|
||||||
if(book.file.exists()) {
|
if (book.file.exists()) {
|
||||||
files.add(book.file);
|
files.add(book.file);
|
||||||
} else {
|
} else {
|
||||||
files.add(new File(book.file + ".part"));
|
files.add(new File(book.file + ".part"));
|
||||||
@ -222,12 +230,12 @@ public class FileUtils {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
String path = book.file.getPath();
|
String path = book.file.getPath();
|
||||||
for(char alphabetFirst = 'a'; alphabetFirst <= 'z'; alphabetFirst++) {
|
for (char alphabetFirst = 'a'; alphabetFirst <= 'z'; alphabetFirst++) {
|
||||||
for(char alphabetSecond = 'a'; alphabetSecond <= 'z'; alphabetSecond++) {
|
for (char alphabetSecond = 'a'; alphabetSecond <= 'z'; alphabetSecond++) {
|
||||||
path = path.substring(0, path.length() - 2) + alphabetFirst + 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));
|
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"));
|
files.add(new File(path + ".part"));
|
||||||
} else {
|
} else {
|
||||||
return files;
|
return files;
|
||||||
@ -267,7 +275,7 @@ public class FileUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFileName (String fileName) {
|
public static String getFileName(String fileName) {
|
||||||
if (new File(fileName).exists()) {
|
if (new File(fileName).exists()) {
|
||||||
return fileName;
|
return fileName;
|
||||||
} else if (new File(fileName + ".part").exists()) {
|
} else if (new File(fileName + ".part").exists()) {
|
||||||
|
@ -163,11 +163,11 @@ public class ZimFileSelectFragment extends BaseFragment
|
|||||||
|
|
||||||
public void checkPermissions() {
|
public void checkPermissions() {
|
||||||
if (ContextCompat.checkSelfPermission(zimManageActivity,
|
if (ContextCompat.checkSelfPermission(zimManageActivity,
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE)
|
Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
!= PackageManager.PERMISSION_GRANTED && Build.VERSION.SDK_INT > 18) {
|
!= PackageManager.PERMISSION_GRANTED && Build.VERSION.SDK_INT > 18) {
|
||||||
Toast.makeText(super.getActivity(), getResources().getString(R.string.request_storage), Toast.LENGTH_LONG)
|
Toast.makeText(super.getActivity(), getResources().getString(R.string.request_storage), Toast.LENGTH_LONG)
|
||||||
.show();
|
.show();
|
||||||
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
REQUEST_STORAGE_PERMISSION);
|
REQUEST_STORAGE_PERMISSION);
|
||||||
} else {
|
} else {
|
||||||
getFiles();
|
getFiles();
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
<item name="android:textColorPrimary">@color/primary_light</item>
|
<item name="android:textColorPrimary">@color/primary_light</item>
|
||||||
<item name="android:textColorSecondary">@color/primary_light</item>
|
<item name="android:textColorSecondary">@color/primary_light</item>
|
||||||
<item name="android:textColorTertiary">@color/primary_light</item>
|
<item name="android:textColorTertiary">@color/primary_light</item>
|
||||||
|
<item name="android:alertDialogTheme">@style/AppTheme.Dialog.Night</item>
|
||||||
<item name="colorControlNormal">@color/accent</item>
|
<item name="colorControlNormal">@color/accent</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -79,10 +80,12 @@
|
|||||||
<style name="AppTheme.Dialog.Night" parent="Theme.AppCompat.DayNight.Dialog.Alert">
|
<style name="AppTheme.Dialog.Night" parent="Theme.AppCompat.DayNight.Dialog.Alert">
|
||||||
<item name="colorAccent">@color/accent</item>
|
<item name="colorAccent">@color/accent</item>
|
||||||
<item name="android:textColorPrimary">@color/white</item>
|
<item name="android:textColorPrimary">@color/white</item>
|
||||||
<item name="android:colorBackground">@color/cardview_dark_background</item>
|
|
||||||
<item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
|
<item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
|
||||||
<item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
|
<item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
|
||||||
<item name="buttonBarNeutralButtonStyle">@style/NeutralButtonStyle</item>
|
<item name="buttonBarNeutralButtonStyle">@style/NeutralButtonStyle</item>
|
||||||
|
<item name="android:textColorAlertDialogListItem">@color/white</item>
|
||||||
|
<item name="android:windowBackground">@color/cardview_dark_background</item>
|
||||||
|
<item name="android:textColorSecondary">@color/primary_light</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="NegativeButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
|
<style name="NegativeButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
|
||||||
|
@ -16,7 +16,7 @@ runID = os.environ['TRAVIS_BUILD_NUMBER']
|
|||||||
apiKey = os.environ['BITBAR_API_KEY']
|
apiKey = os.environ['BITBAR_API_KEY']
|
||||||
testName = "Auto Test {}".format(runID)
|
testName = "Auto Test {}".format(runID)
|
||||||
|
|
||||||
for x in range(0, 50):
|
for x in range(0, 200):
|
||||||
r = requests.get('https://cloud.testdroid.com/api/me/projects/{}/runs'.format(PROJECT_ID), auth=(apiKey, ''), headers={"Accept" : "application/json"})
|
r = requests.get('https://cloud.testdroid.com/api/me/projects/{}/runs'.format(PROJECT_ID), auth=(apiKey, ''), headers={"Accept" : "application/json"})
|
||||||
result = list(filter(lambda run: run.get("displayName") == testName, r.json().get("data")))
|
result = list(filter(lambda run: run.get("displayName") == testName, r.json().get("data")))
|
||||||
if len(result) > 0 and result[0].get("state") == "FINISHED":
|
if len(result) > 0 and result[0].get("state") == "FINISHED":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user