diff options
author | Joey Rizzoli <joey@lineageos.org> | 2017-04-20 21:36:40 +0200 |
---|---|---|
committer | Joey Rizzoli <joey@lineageos.org> | 2017-04-20 21:38:16 +0200 |
commit | 60de8781c2bf6ebfdbfd51d2657a715ce5a5f2ff (patch) | |
tree | a05b72007bbfab536611ec6c84b513220640b0dd | |
parent | c11c303e26a04ef128a7811d9a246de0543e007d (diff) | |
download | android_packages_apps_Jelly-60de8781c2bf6ebfdbfd51d2657a715ce5a5f2ff.tar.gz android_packages_apps_Jelly-60de8781c2bf6ebfdbfd51d2657a715ce5a5f2ff.tar.bz2 android_packages_apps_Jelly-60de8781c2bf6ebfdbfd51d2657a715ce5a5f2ff.zip |
Initial push
Signed-off-by: Joey Rizzoli <joey@lineageos.org>
68 files changed, 3783 insertions, 2 deletions
@@ -1,8 +1,7 @@ *.iml .gradle /local.properties -/.idea/workspace.xml -/.idea/libraries +/.idea .DS_Store /build /captures diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..16834b8 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,36 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + defaultConfig { + applicationId "org.lineageos.jelly" + minSdkVersion 23 + targetSdkVersion 25 + versionCode 1 + versionName "1.0" + jackOptions.enabled true + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + lintOptions { + disable 'RestrictedApi' + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:design:25.3.1' + compile 'com.android.support:cardview-v7:25.3.1' + compile 'com.android.support:palette-v7:25.3.1' + compile 'com.android.support:support-v4:25.3.1' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..5f7e87d --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /home/joey/android/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +-keepclassmembers class fqcn.of.javascript.interface.for.webview { + public *; +} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a2875f9 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.lineageos.jelly"> + + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> + <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> + + <application + android:allowBackup="true" + android:fullBackupContent="@xml/backup_descriptor" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:supportsRtl="true" + android:theme="@style/AppTheme"> + + <activity + android:name="org.lineageos.jelly.MainActivity" + android:documentLaunchMode="always" + android:hardwareAccelerated="true" + android:label="@string/app_name" + android:persistent="true" + android:theme="@style/AppTheme.NoActionBar" + android:windowSoftInputMode="stateHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + <intent-filter> + <action android:name="android.intent.action.VIEW" /> + + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + + <data android:scheme="http" /> + <data android:scheme="https" /> + </intent-filter> + <intent-filter> + <action android:name="android.intent.action.VIEW" /> + + <category android:name="android.intent.category.BROWSABLE" /> + <category android:name="android.intent.category.DEFAULT" /> + + <data android:scheme="http" /> + <data android:scheme="https" /> + <data android:mimeType="text/html" /> + <data android:mimeType="text/plain" /> + <data android:mimeType="application/xhtml+xml" /> + <data android:mimeType="application/vnd.wap.xhtml+xml" /> + </intent-filter> + </activity> + + <activity + android:name="org.lineageos.jelly.history.HistoryActivity" + android:label="@string/history_title" + android:theme="@style/AppTheme.NoActionBar" /> + + <activity + android:name="org.lineageos.jelly.favorite.FavoriteActivity" + android:label="@string/favorite_title" + android:theme="@style/AppTheme.NoActionBar" /> + + <activity + android:name="org.lineageos.jelly.SettingsActivity" + android:label="@string/settings_title" + android:theme="@style/AppTheme.NoActionBar" /> + + <provider + android:name="android.support.v4.content.FileProvider" + android:authorities="org.lineageos.jelly.fileprovider" + android:exported="false" + android:grantUriPermissions="true"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/file_provider" /> + </provider> + </application> +</manifest> diff --git a/app/src/main/java/org/lineageos/jelly/MainActivity.java b/app/src/main/java/org/lineageos/jelly/MainActivity.java new file mode 100644 index 0000000..75793fc --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/MainActivity.java @@ -0,0 +1,395 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.ActivityManager; +import android.app.DownloadManager; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.ColorDrawable; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.support.annotation.NonNull; +import android.support.design.widget.BottomSheetDialog; +import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.Snackbar; +import android.support.v4.content.ContextCompat; +import android.support.v4.content.FileProvider; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.view.menu.MenuBuilder; +import android.support.v7.view.menu.MenuPopupHelper; +import android.support.v7.widget.PopupMenu; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.ContextThemeWrapper; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.View; +import android.view.WindowManager; +import android.webkit.CookieManager; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ProgressBar; + +import org.lineageos.jelly.favorite.Favorite; +import org.lineageos.jelly.favorite.FavoriteActivity; +import org.lineageos.jelly.favorite.FavoriteDatabaseHandler; +import org.lineageos.jelly.history.HistoryActivity; +import org.lineageos.jelly.utils.PrefsUtils; +import org.lineageos.jelly.utils.UiUtils; +import org.lineageos.jelly.webview.WebViewExt; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; + +public class MainActivity extends AppCompatActivity { + public static final int FILE_CHOOSER_REQ = 421; + private static final String TAG = MainActivity.class.getSimpleName(); + private static final String PROVIDER = "org.lineageos.jelly.fileprovider"; + private static final String EXTRA_INCOGNITO = "extra_incognito"; + private static final int STORAGE_PERM_REQ = 423; + private static final int LOCATION_PERM_REQ = 424; + + private CoordinatorLayout mCoordinator; + private WebViewExt mWebView; + + private Bitmap mUrlIcon; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_main); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + mCoordinator = (CoordinatorLayout) findViewById(R.id.coordinator_layout); + SwipeRefreshLayout refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh); + refreshLayout.setOnRefreshListener(() -> { + mWebView.reload(); + new Handler().postDelayed(() -> refreshLayout.setRefreshing(false), 1000); + }); + ProgressBar progressBar = (ProgressBar) findViewById(R.id.load_progress); + EditText editText = (EditText) findViewById(R.id.url_bar); + editText.setOnKeyListener((v, keyCode, event) -> { + if (event.getAction() != KeyEvent.ACTION_DOWN) { + return true; + } + + switch (keyCode) { + case KeyEvent.KEYCODE_ENTER: + case KeyEvent.KEYCODE_DPAD_CENTER: + case KeyEvent.KEYCODE_NUMPAD_ENTER: + mWebView.loadUrl(editText.getText().toString()); + break; + } + return true; + }); + + Intent intent = getIntent(); + String url = intent.getDataString(); + boolean incognito = intent.getBooleanExtra(EXTRA_INCOGNITO, false); + + // Make sure prefs are set before loading them + PreferenceManager.setDefaultValues(this, R.xml.settings, false); + + setupMenu(); + mWebView = (WebViewExt) findViewById(R.id.web_view); + mWebView.init(this, editText, progressBar, incognito); + mWebView.loadUrl(url == null ? PrefsUtils.getHomePage(this) : url); + } + + @Override + protected void onResume() { + CookieManager.setAcceptFileSchemeCookies(PrefsUtils.getCookie(this)); + + super.onResume(); + if (PrefsUtils.getLookLock(this)) { + getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, + WindowManager.LayoutParams.FLAG_SECURE); + } else { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE); + } + } + + @Override + public void onBackPressed() { + if (mWebView.canGoBack()) { + mWebView.goBack(); + } else { + super.onBackPressed(); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] results) { + switch (requestCode) { + case LOCATION_PERM_REQ: + if (hasLocationPermission()) { + mWebView.reload(); + } + break; + case STORAGE_PERM_REQ: + if (hasStoragePermission()) { + if (shouldShowRequestPermissionRationale( + Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + new AlertDialog.Builder(this) + .setTitle(R.string.permission_error_title) + .setMessage(R.string.permission_error_storage) + .setCancelable(false) + .setPositiveButton(getString(R.string.permission_error_ask_again), + ((dialog, which) -> requestStoragePermission())) + .setNegativeButton(getString(R.string.dismiss), + (((dialog, which) -> dialog.dismiss()))) + .show(); + } else { + Snackbar.make(mCoordinator, getString(R.string.permission_error_forever), + Snackbar.LENGTH_LONG).show(); + } + } + break; + } + + } + + private void setupMenu() { + ImageButton menu = (ImageButton) findViewById(R.id.search_menu); + menu.setOnClickListener(v -> { + ContextThemeWrapper wrapper = new ContextThemeWrapper(this, + R.style.AppTheme_PopupMenuOverlapAnchor); + + PopupMenu popupMenu = new PopupMenu(wrapper, menu, Gravity.NO_GRAVITY, + R.attr.actionOverflowMenuStyle, 0); + popupMenu.inflate(R.menu.menu_main); + popupMenu.setOnMenuItemClickListener(item -> { + switch (item.getItemId()) { + case R.id.menu_new: + openInNewTab(null); + break; + case R.id.menu_incognito: + Intent intent = new Intent(this, MainActivity.class); + intent.putExtra(EXTRA_INCOGNITO, true); + startActivity(intent); + break; + case R.id.menu_reload: + mWebView.reload(); + break; + case R.id.menu_add_favorite: + setAsFavorite(mWebView.getTitle(), mWebView.getUrl()); + break; + case R.id.menu_share: + // Delay a bit to allow popup menu hide animation to play + new Handler().postDelayed(() -> shareUrl(mWebView.getUrl()), 300); + break; + case R.id.menu_favorite: + startActivity(new Intent(this, FavoriteActivity.class)); + break; + case R.id.menu_history: + startActivity(new Intent(this, HistoryActivity.class)); + break; + case R.id.menu_shortcut: + addShortcut(); + break; + case R.id.menu_settings: + startActivity(new Intent(this, SettingsActivity.class)); + break; + } + return true; + }); + + // Fuck you, lint + //noinspection RestrictedApi + MenuPopupHelper helper = new MenuPopupHelper(wrapper, + (MenuBuilder) popupMenu.getMenu(), menu); + //noinspection RestrictedApi + helper.setForceShowIcon(true); + //noinspection RestrictedApi + helper.show(); + }); + } + + private void openInNewTab(String url) { + Intent intent = new Intent(this, MainActivity.class); + intent.setData(Uri.parse(url)); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + startActivity(intent); + } + + private void shareUrl(String url) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.putExtra(Intent.EXTRA_TEXT, url); + + if (PrefsUtils.getAdvancedShare(this) && url.equals(mWebView.getUrl())) { + try { + File file = new File(getCacheDir(), + String.valueOf(System.currentTimeMillis()) + ".png"); + FileOutputStream out = new FileOutputStream(file); + Bitmap bm = mWebView.getSnap(); + if (bm == null) { + return; + } + bm.compress(Bitmap.CompressFormat.PNG, 70, out); + out.flush(); + out.close(); + intent.putExtra(Intent.EXTRA_STREAM, + FileProvider.getUriForFile(this, PROVIDER, file)); + intent.setType("image/png"); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } catch (IOException e) { + Log.e(TAG, e.getMessage()); + } + } else { + intent.setType("text/plain"); + } + + startActivity(intent); + } + + private void setAsFavorite(String title, String url) { + FavoriteDatabaseHandler handler = new FavoriteDatabaseHandler(this); + boolean hasValidIcon = mUrlIcon != null && !mUrlIcon.isRecycled(); + handler.addItem(new Favorite(title, url, hasValidIcon ? + UiUtils.getColor(this, mUrlIcon, false) : + ContextCompat.getColor(this, R.color.colorAccent))); + Snackbar.make(mCoordinator, getString(R.string.favorite_added), + Snackbar.LENGTH_LONG).show(); + } + + public void downloadFileAsk(String url, String fileName) { + if (!hasStoragePermission()) { + requestStoragePermission(); + return; + } + + new AlertDialog.Builder(this) + .setTitle(R.string.download_title) + .setMessage(getString(R.string.download_message, fileName)) + .setPositiveButton(getString(R.string.download_positive), + (dialog, which) -> fetchFile(url, fileName)) + .setNegativeButton(getString(R.string.dismiss), + ((dialog, which) -> dialog.dismiss())) + .show(); + } + + private void fetchFile(String url, String fileName) { + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); + DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); + manager.enqueue(request); + } + + public void showSheetMenu(String url, boolean shouldAllowDownload) { + final BottomSheetDialog sheet = new BottomSheetDialog(this); + + @SuppressLint("InflateParams") + View view = getLayoutInflater().inflate(R.layout.sheet_actions, null); + View tabLayout = view.findViewById(R.id.sheet_new_tab); + View shareLayout = view.findViewById(R.id.sheet_share); + View favouriteLayout = view.findViewById(R.id.sheet_favourite); + View downloadLayout = view.findViewById(R.id.sheet_download); + + tabLayout.setOnClickListener(v -> openInNewTab(url)); + shareLayout.setOnClickListener(v -> shareUrl(url)); + favouriteLayout.setOnClickListener(v -> setAsFavorite(url, url)); + if (shouldAllowDownload) { + downloadLayout.setOnClickListener(v -> downloadFileAsk(url, "")); + downloadLayout.setVisibility(View.VISIBLE); + } + sheet.setContentView(view); + sheet.show(); + } + + private void requestStoragePermission() { + String[] permissionArray = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; + requestPermissions(permissionArray, STORAGE_PERM_REQ); + } + + private boolean hasStoragePermission() { + int result = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE); + return result == PackageManager.PERMISSION_GRANTED; + } + + public void requestLocationPermission() { + String[] permissionArray = new String[]{Manifest.permission.ACCESS_FINE_LOCATION}; + requestPermissions(permissionArray, LOCATION_PERM_REQ); + } + + public boolean hasLocationPermission() { + int result = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION); + return result == PackageManager.PERMISSION_GRANTED; + } + + public void setColor(Bitmap favicon, boolean incognito) { + ActionBar actionBar = getSupportActionBar(); + if (favicon == null || favicon.isRecycled() || actionBar == null) { + return; + } + + mUrlIcon = favicon.copy(favicon.getConfig(), true); + int color = UiUtils.getColor(this, favicon, incognito); + actionBar.setBackgroundDrawable(new ColorDrawable(color)); + getWindow().setStatusBarColor(color); + + int flags = getWindow().getDecorView().getSystemUiVisibility(); + if (UiUtils.isColorLight(color)) { + flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } else { + flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + getWindow().getDecorView().setSystemUiVisibility(flags); + + setTaskDescription(new ActivityManager.TaskDescription(mWebView.getTitle(), + favicon, color)); + + if (!favicon.isRecycled()) { + favicon.recycle(); + } + } + + private void addShortcut() { + Intent intent = new Intent(this, MainActivity.class); + intent.setData(Uri.parse(mWebView.getUrl())); + intent.setAction(Intent.ACTION_MAIN); + + Bitmap icon = mUrlIcon == null ? + BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher) : mUrlIcon; + Bitmap launcherIcon = UiUtils.getShortcutIcon(this, icon); + + Intent addIntent = new Intent(); + addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, mWebView.getTitle()); + addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, launcherIcon); + addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent); + addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); + sendBroadcast(addIntent); + launcherIcon.recycle(); + Snackbar.make(mCoordinator, getString(R.string.shortcut_added), + Snackbar.LENGTH_LONG).show(); + } +} diff --git a/app/src/main/java/org/lineageos/jelly/SettingsActivity.java b/app/src/main/java/org/lineageos/jelly/SettingsActivity.java new file mode 100644 index 0000000..aa57a55 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/SettingsActivity.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly; + +import android.os.Bundle; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +// "noSuchMethodError" is thrown if lambda is used in this class (wtf) +@SuppressWarnings("Convert2Lambda") +public class SettingsActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_settings); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + toolbar.setNavigationIcon(R.drawable.ic_back); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + public static class MyPreferenceFragment extends PreferenceFragment { + + @Override + public void onCreate(Bundle savedInstance) { + super.onCreate(savedInstance); + addPreferencesFromResource(R.xml.settings); + + Preference homePage = findPreference("key_home_page"); + homePage.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + homePage.setSummary(newValue.toString()); + return true; + } + }); + if (homePage.getSummary() == null) { + homePage.setSummary(getString(R.string.default_home_page)); + } + } + } +} diff --git a/app/src/main/java/org/lineageos/jelly/favorite/Favorite.java b/app/src/main/java/org/lineageos/jelly/favorite/Favorite.java new file mode 100644 index 0000000..9f0096d --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/favorite/Favorite.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.favorite; + +public class Favorite { + private long id = -1; + private String title; + private String url; + private int color; + + public Favorite(String title, String url, int color) { + this.title = title; + this.url = url; + this.color = color; + } + + Favorite(long id, String title, String url, int color) { + this.id = id; + this.title = title; + this.url = url; + this.color = color; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + String getUrl() { + return url; + } + + void setUrl(String url) { + this.url = url; + } + + public int getColor() { + return color; + } +} diff --git a/app/src/main/java/org/lineageos/jelly/favorite/FavoriteActivity.java b/app/src/main/java/org/lineageos/jelly/favorite/FavoriteActivity.java new file mode 100644 index 0000000..c8d8bbd --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/favorite/FavoriteActivity.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.favorite; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.EditText; + +import org.lineageos.jelly.R; +import org.lineageos.jelly.utils.UiUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class FavoriteActivity extends AppCompatActivity { + private RecyclerView mList; + private View mEmptyView; + + private FavoriteDatabaseHandler mDbHandler; + private FavoriteAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstance) { + super.onCreate(savedInstance); + + setContentView(R.layout.activity_favorites); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + toolbar.setNavigationIcon(R.drawable.ic_back); + toolbar.setNavigationOnClickListener(v -> finish()); + + mList = (RecyclerView) findViewById(R.id.favorite_list); + mEmptyView = findViewById(R.id.favorite_empty_layout); + + mDbHandler = new FavoriteDatabaseHandler(this); + mAdapter = new FavoriteAdapter(this, new ArrayList<>()); + mList.setLayoutManager(new GridLayoutManager(this, 2)); + mList.setItemAnimator(new DefaultItemAnimator()); + mList.setAdapter(mAdapter); + + int listTop = mList.getTop(); + mList.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + + toolbar.setElevation(recyclerView.getChildAt(0).getTop() < listTop ? + UiUtils.dpToPx(getResources(), 8) : 0); + } + }); + } + + @Override + public void onResume() { + super.onResume(); + refresh(); + } + + void refresh() { + List<Favorite> items = mDbHandler.getAllItems(); + // Reverse database list order + Collections.reverse(items); + mAdapter.updateList(items); + + if (items.isEmpty()) { + mList.setVisibility(View.GONE); + mEmptyView.setVisibility(View.VISIBLE); + } + } + + boolean editItem(Favorite item) { + @SuppressLint("InflateParams") + View view = LayoutInflater.from(this).inflate(R.layout.dialog_favorite_edit, null); + EditText titleEdit = (EditText) view.findViewById(R.id.favorite_edit_title); + EditText urlEdit = (EditText) view.findViewById(R.id.favorite_edit_url); + + titleEdit.setText(item.getTitle()); + urlEdit.setText(item.getUrl()); + + String error = getString(R.string.favorite_edit_error); + urlEdit.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (!s.toString().contains("http")) { + urlEdit.setError(error); + } + } + + @Override + public void afterTextChanged(Editable s) { + if (!s.toString().contains("http")) { + urlEdit.setError(error); + } + } + }); + + new AlertDialog.Builder(this) + .setTitle(R.string.favorite_edit_dialog_title) + .setView(view) + .setPositiveButton(R.string.favorite_edit_positive, + ((dialog, which) -> { + String url = urlEdit.getText().toString(); + String title = titleEdit.getText().toString(); + if (url.isEmpty()) { + urlEdit.setError(error); + urlEdit.requestFocus(); + } + item.setTitle(title); + item.setUrl(url); + mDbHandler.updateItem(item); + refresh(); + dialog.dismiss(); + })) + .setNeutralButton(R.string.favorite_edit_delete, + (dialog, which) -> { + mDbHandler.deleteItem(item.getId()); + mAdapter.removeItem(item.getId()); + dialog.dismiss(); + }) + .setNegativeButton(android.R.string.cancel, + (dialog, which) -> dialog.dismiss()) + .show(); + return true; + } + +} diff --git a/app/src/main/java/org/lineageos/jelly/favorite/FavoriteAdapter.java b/app/src/main/java/org/lineageos/jelly/favorite/FavoriteAdapter.java new file mode 100644 index 0000000..e315f75 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/favorite/FavoriteAdapter.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.favorite; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import org.lineageos.jelly.R; + +import java.util.List; + +class FavoriteAdapter extends RecyclerView.Adapter<FavoriteHolder> { + private final Context mContext; + private List<Favorite> mList; + + FavoriteAdapter(Context context, List<Favorite> list) { + mContext = context; + mList = list; + } + + @Override + public FavoriteHolder onCreateViewHolder(ViewGroup parent, int type) { + return new FavoriteHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_favorite, parent, false)); + } + + @Override + public void onBindViewHolder(FavoriteHolder holder, int position) { + holder.setData(mContext, mList.get(position)); + } + + @Override + public int getItemCount() { + return mList.size(); + } + + void updateList(List<Favorite> list) { + mList = list; + notifyDataSetChanged(); + } + + void removeItem(long id) { + int position = 0; + for (; position < mList.size(); position++) { + if (mList.get(position).getId() == id) { + break; + } + } + + if (position == mList.size()) { + return; + } + + mList.remove(position); + notifyItemRemoved(position); + + if (mList.isEmpty()) { + // Show empty status + ((FavoriteActivity) mContext).refresh(); + } + } +} diff --git a/app/src/main/java/org/lineageos/jelly/favorite/FavoriteDatabaseHandler.java b/app/src/main/java/org/lineageos/jelly/favorite/FavoriteDatabaseHandler.java new file mode 100644 index 0000000..e54537b --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/favorite/FavoriteDatabaseHandler.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.favorite; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import java.util.ArrayList; +import java.util.List; + +public class FavoriteDatabaseHandler extends SQLiteOpenHelper { + private static final int DB_VERSION = 1; + private static final String DB_NAME = "FavoriteDatabase"; + private static final String DB_TABLE_FAVORITES = "favorites"; + private static final String KEY_ID = "id"; + private static final String KEY_TITLE = "title"; + private static final String KEY_URL = "url"; + private static final String KEY_COLOR = "color"; + + + public FavoriteDatabaseHandler(Context context) { + super(context, DB_NAME, null, DB_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL("CREATE TABLE " + DB_TABLE_FAVORITES + " (" + + KEY_ID + " INTEGER PRIMARY KEY, " + + KEY_TITLE + " TEXT, " + + KEY_URL + " TEXT, " + + KEY_COLOR + " INTEGER)"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + // Update this when db table will be changed + } + + public void addItem(Favorite item) { + if (item.getId() == -1) { + item.setId(System.currentTimeMillis()); + } + + ContentValues values = new ContentValues(); + values.put(KEY_ID, item.getId()); + values.put(KEY_TITLE, item.getTitle()); + values.put(KEY_URL, item.getUrl()); + values.put(KEY_COLOR, item.getColor()); + + SQLiteDatabase db = getWritableDatabase(); + db.insert(DB_TABLE_FAVORITES, null, values); + db.close(); + } + + void updateItem(Favorite item) { + SQLiteDatabase db = getWritableDatabase(); + + ContentValues values = new ContentValues(); + values.put(KEY_TITLE, item.getTitle()); + values.put(KEY_URL, item.getUrl()); + values.put(KEY_COLOR, item.getColor()); + + db.update(DB_TABLE_FAVORITES, values, KEY_ID + "=?", + new String[]{String.valueOf(item.getId())}); + } + + void deleteItem(long id) { + SQLiteDatabase db = getWritableDatabase(); + db.delete(DB_TABLE_FAVORITES, KEY_ID + "=?", new String[]{String.valueOf(id)}); + db.close(); + } + + List<Favorite> getAllItems() { + List<Favorite> list = new ArrayList<>(); + SQLiteDatabase db = getWritableDatabase(); + Cursor cursor = db.rawQuery("SELECT * FROM " + DB_TABLE_FAVORITES, null); + + if (cursor.moveToFirst()) { + do { + list.add(new Favorite(Long.parseLong(cursor.getString(0)), + cursor.getString(1), cursor.getString(2), + Integer.parseInt(cursor.getString(3)))); + } while (cursor.moveToNext()); + } + cursor.close(); + db.close(); + return list; + } +} diff --git a/app/src/main/java/org/lineageos/jelly/favorite/FavoriteHolder.java b/app/src/main/java/org/lineageos/jelly/favorite/FavoriteHolder.java new file mode 100644 index 0000000..ffc2726 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/favorite/FavoriteHolder.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.favorite; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.net.Uri; +import android.support.v7.widget.CardView; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.TextView; + +import org.lineageos.jelly.MainActivity; +import org.lineageos.jelly.R; +import org.lineageos.jelly.utils.UiUtils; + +class FavoriteHolder extends RecyclerView.ViewHolder { + private final CardView mCard; + private final TextView mTitle; + + FavoriteHolder(View view) { + super(view); + mCard = (CardView) view.findViewById(R.id.row_favorite_card); + mTitle = (TextView) view.findViewById(R.id.row_favorite_title); + } + + void setData(Context context, Favorite item) { + String title = item.getTitle(); + if (title == null || title.isEmpty()) { + title = item.getUrl().split("/")[2]; + } + mTitle.setText(title); + mTitle.setTextColor(UiUtils.isColorLight(item.getColor()) ? Color.BLACK : Color.WHITE); + mCard.setCardBackgroundColor(item.getColor()); + + mCard.setOnClickListener(v -> { + Intent intent = new Intent(context, MainActivity.class); + intent.setData(Uri.parse(item.getUrl())); + context.startActivity(intent); + }); + + mCard.setOnLongClickListener(v -> ((FavoriteActivity) context).editItem(item)); + } +} diff --git a/app/src/main/java/org/lineageos/jelly/history/HistoryActivity.java b/app/src/main/java/org/lineageos/jelly/history/HistoryActivity.java new file mode 100644 index 0000000..03cb994 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/history/HistoryActivity.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.history; + +import android.app.ProgressDialog; +import android.os.AsyncTask; +import android.os.Bundle; +import android.os.Handler; +import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + +import org.lineageos.jelly.R; +import org.lineageos.jelly.utils.UiUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class HistoryActivity extends AppCompatActivity { + private RecyclerView mList; + private View mEmptyView; + + private HistoryDatabaseHandler mDbHandler; + private HistoryAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstance) { + super.onCreate(savedInstance); + + setContentView(R.layout.activity_history); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + toolbar.setNavigationIcon(R.drawable.ic_back); + toolbar.setNavigationOnClickListener(v -> finish()); + + mList = (RecyclerView) findViewById(R.id.history_list); + mEmptyView = findViewById(R.id.history_empty_layout); + + mDbHandler = new HistoryDatabaseHandler(this); + mAdapter = new HistoryAdapter(this, new ArrayList<>()); + mList.setLayoutManager(new LinearLayoutManager(this)); + mList.setItemAnimator(new DefaultItemAnimator()); + mList.setAdapter(mAdapter); + + int listTop = mList.getTop(); + mList.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + + toolbar.setElevation(recyclerView.getChildAt(0).getTop() < listTop ? + UiUtils.dpToPx(getResources(), 8) : 0); + } + }); + } + + @Override + public void onResume() { + super.onResume(); + refresh(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_history, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() != R.id.menu_history_delete) { + return super.onOptionsItemSelected(item); + } + + new AlertDialog.Builder(this) + .setTitle(R.string.history_delete_title) + .setMessage(R.string.history_delete_message) + .setPositiveButton(R.string.history_delete_positive, + (dialog, which) -> deleteAll()) + .setNegativeButton(android.R.string.cancel, (d, w) -> d.dismiss()) + .show(); + return true; + } + + void refresh() { + List<HistoryItem> items = mDbHandler.getAllItems(); + // Reverse database list order + Collections.reverse(items); + mAdapter.updateList(items); + + if (items.isEmpty()) { + mList.setVisibility(View.GONE); + mEmptyView.setVisibility(View.VISIBLE); + } + } + + private void deleteAll() { + ProgressDialog dialog = new ProgressDialog(this); + dialog.setTitle(getString(R.string.history_delete_title)); + dialog.setMessage(getString(R.string.history_deleting_message)); + dialog.setCancelable(false); + dialog.setIndeterminate(true); + dialog.show(); + + new AsyncTask<Void, Void, Boolean>() { + @Override + protected Boolean doInBackground(Void... params) { + mDbHandler.deleteAll(); + return true; + } + + @Override + protected void onPostExecute(Boolean param) { + new Handler().postDelayed(() -> { + dialog.dismiss(); + refresh(); + }, 1000); + } + }.execute(); + } + + HistoryAdapter getAdapter() { + return mAdapter; + } +} diff --git a/app/src/main/java/org/lineageos/jelly/history/HistoryAdapter.java b/app/src/main/java/org/lineageos/jelly/history/HistoryAdapter.java new file mode 100644 index 0000000..cf11923 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/history/HistoryAdapter.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.history; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import org.lineageos.jelly.R; + +import java.util.List; + +class HistoryAdapter extends RecyclerView.Adapter<HistoryHolder> { + + private final Context mContext; + private List<HistoryItem> mList; + + HistoryAdapter(Context context, List<HistoryItem> list) { + mContext = context; + mList = list; + } + + @Override + public HistoryHolder onCreateViewHolder(ViewGroup parent, int type) { + return new HistoryHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_history, parent, false)); + } + + @Override + public void onBindViewHolder(HistoryHolder holder, int position) { + holder.setData(mContext, mList.get(position)); + } + + @Override + public int getItemCount() { + return mList.size(); + } + + void updateList(List<HistoryItem> list) { + mList = list; + notifyDataSetChanged(); + } + + void removeItem(long id) { + int position = 0; + for (; position < mList.size(); position++) { + if (mList.get(position).getId() == id) { + break; + } + } + + if (position == mList.size()) { + return; + } + + mList.remove(position); + notifyItemRemoved(position); + + if (mList.isEmpty()) { + // Show empty status + ((HistoryActivity) mContext).refresh(); + } + } +} diff --git a/app/src/main/java/org/lineageos/jelly/history/HistoryDatabaseHandler.java b/app/src/main/java/org/lineageos/jelly/history/HistoryDatabaseHandler.java new file mode 100644 index 0000000..6b977cf --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/history/HistoryDatabaseHandler.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.history; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import java.util.ArrayList; +import java.util.List; + +public class HistoryDatabaseHandler extends SQLiteOpenHelper { + + private static final int DB_VERSION = 1; + private static final String DB_NAME = "HistoryDatabase"; + private static final String DB_TABLE_HISTORY = "history"; + private static final String KEY_ID = "id"; + private static final String KEY_TITLE = "title"; + private static final String KEY_URL = "url"; + + + public HistoryDatabaseHandler(Context context) { + super(context, DB_NAME, null, DB_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL("CREATE TABLE " + DB_TABLE_HISTORY + " (" + + KEY_ID + " INTEGER PRIMARY KEY, " + + KEY_TITLE + " TEXT, " + + KEY_URL + " TEXT)"); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + // Update this when db table will be changed + } + + public void addItem(HistoryItem item) { + if (item.getId() == -1) { + item.setId(System.currentTimeMillis()); + } + + ContentValues values = new ContentValues(); + values.put(KEY_ID, item.getId()); + values.put(KEY_TITLE, item.getTitle()); + values.put(KEY_URL, item.getUrl()); + + SQLiteDatabase db = getWritableDatabase(); + db.insert(DB_TABLE_HISTORY, null, values); + db.close(); + } + + void deleteItem(long id) { + SQLiteDatabase db = getWritableDatabase(); + db.delete(DB_TABLE_HISTORY, KEY_ID + "=?", new String[]{String.valueOf(id)}); + db.close(); + } + + List<HistoryItem> getAllItems() { + List<HistoryItem> list = new ArrayList<>(); + SQLiteDatabase db = getWritableDatabase(); + Cursor cursor = db.rawQuery("SELECT * FROM " + DB_TABLE_HISTORY, null); + + if (cursor.moveToFirst()) { + do { + list.add(new HistoryItem(Long.parseLong(cursor.getString(0)), + cursor.getString(1), cursor.getString(2))); + } while (cursor.moveToNext()); + } + cursor.close(); + db.close(); + return list; + } + + void deleteAll() { + SQLiteDatabase db = getWritableDatabase(); + db.delete(DB_TABLE_HISTORY, KEY_ID + ">=?", new String[]{"0"}); + db.close(); + } +} diff --git a/app/src/main/java/org/lineageos/jelly/history/HistoryHolder.java b/app/src/main/java/org/lineageos/jelly/history/HistoryHolder.java new file mode 100644 index 0000000..12887d9 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/history/HistoryHolder.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.history; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.v4.content.ContextCompat; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.lineageos.jelly.MainActivity; +import org.lineageos.jelly.R; +import org.lineageos.jelly.utils.UiUtils; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +class HistoryHolder extends RecyclerView.ViewHolder { + + private final LinearLayout mRootLayout; + private final TextView mTitle; + private final TextView mSummary; + + HistoryHolder(View view) { + super(view); + mRootLayout = (LinearLayout) view.findViewById(R.id.row_history_layout); + mTitle = (TextView) view.findViewById(R.id.row_history_title); + mSummary = (TextView) view.findViewById(R.id.row_history_summary); + } + + void setData(Context context, HistoryItem item) { + String title = item.getTitle(); + if (title == null || title.isEmpty()) { + title = item.getUrl().split("/")[2]; + } + mTitle.setText(title); + mSummary.setText(new SimpleDateFormat(context.getString(R.string.history_date_format), + Locale.getDefault()).format(new Date(item.getId()))); + + mRootLayout.setOnClickListener(v -> { + Intent intent = new Intent(context, MainActivity.class); + intent.setData(Uri.parse(item.getUrl())); + context.startActivity(intent); + }); + + mRootLayout.setOnLongClickListener(v -> { + new HistoryDatabaseHandler(context).deleteItem(item.getId()); + ((HistoryActivity) context).getAdapter().removeItem(item.getId()); + return true; + }); + + int background; + switch (UiUtils.getPositionInTime(item.getId())) { + case 0: + background = R.color.history_last_hour; + break; + case 1: + background = R.color.history_today; + break; + case 2: + background = R.color.history_this_week; + break; + case 3: + background = R.color.history_this_month; + break; + default: + background = R.color.history_earlier; + break; + } + mRootLayout.setBackgroundColor(ContextCompat.getColor(context, background)); + } +} diff --git a/app/src/main/java/org/lineageos/jelly/history/HistoryItem.java b/app/src/main/java/org/lineageos/jelly/history/HistoryItem.java new file mode 100644 index 0000000..d8fbded --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/history/HistoryItem.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.history; + +public class HistoryItem { + + private final String title; + private final String url; + private long id = -1; + + public HistoryItem(String title, String url) { + this.title = title; + this.url = url; + } + + HistoryItem(long id, String title, String url) { + this.id = id; + this.title = title; + this.url = url; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + String getUrl() { + return url; + } +} diff --git a/app/src/main/java/org/lineageos/jelly/ui/EditTextExt.java b/app/src/main/java/org/lineageos/jelly/ui/EditTextExt.java new file mode 100644 index 0000000..3074f9f --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/ui/EditTextExt.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.ui; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Shader; +import android.support.v7.widget.AppCompatEditText; +import android.util.AttributeSet; + +public class EditTextExt extends AppCompatEditText { + + private int mPositionX; + + public EditTextExt(Context context) { + super(context); + } + + public EditTextExt(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public EditTextExt(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + private static LinearGradient getGradient(float widthEnd, float fadeStart, + float stopStart, float stopEnd, int color) { + return new LinearGradient(0, 0, widthEnd, 0, + new int[] { color, Color.TRANSPARENT, color, color, Color.TRANSPARENT }, + new float[] { 0, fadeStart, stopStart, stopEnd, 1f }, Shader.TileMode.CLAMP); + } + + @Override + protected void onScrollChanged(int x, int y, int oldX, int oldY) { + super.onScrollChanged(x, y, oldX, oldY); + mPositionX = x; + requestLayout(); + } + + @Override + public void onDraw(Canvas canvas) { + float lineWidth = getLayout().getLineWidth(0); + float width = getMeasuredWidth(); + + if (getText() == null || getText().length() == 0 || lineWidth <= width) { + super.onDraw(canvas); + getPaint().setShader(null); + return; + } + + int textColor = getCurrentTextColor(); + float widthEnd = width + mPositionX; + float percent = (int) (width * 0.2); + + float fadeStart = mPositionX / widthEnd; + + float stopStart = mPositionX > 0 ? ((mPositionX + percent) / widthEnd) : 0; + float stopEnd = (widthEnd - (lineWidth > widthEnd ? percent : 0)) / widthEnd; + getPaint().setShader(getGradient(widthEnd, fadeStart, stopStart, stopEnd, textColor)); + super.onDraw(canvas); + } +} diff --git a/app/src/main/java/org/lineageos/jelly/utils/PrefsUtils.java b/app/src/main/java/org/lineageos/jelly/utils/PrefsUtils.java new file mode 100644 index 0000000..47bb137 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/utils/PrefsUtils.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.utils; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import org.lineageos.jelly.R; + +public final class PrefsUtils { + private static final String KEY_SEARCH_ENGINE = "key_search_engine"; + private static final String KEY_HOME_PAGE = "key_home_page"; + private static final String KEY_ADVANCED_SHARE = "key_advanced_share"; + private static final String KEY_LOOKLOCK = "key_looklock"; + private static final String KEY_JS = "key_javascript"; + private static final String KEY_LOCATION = "key_location"; + private static final String KEY_COOKIE = "key_cookie"; + + private PrefsUtils() { + } + + public static String getSearchEngine(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getString(KEY_SEARCH_ENGINE, + context.getString(R.string.default_search_engine)); + } + + public static String getHomePage(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getString(KEY_HOME_PAGE, context.getString(R.string.default_home_page)); + } + + public static boolean getAdvancedShare(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getBoolean(KEY_ADVANCED_SHARE, false); + } + + public static boolean getLookLock(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getBoolean(KEY_LOOKLOCK, false); + } + + public static boolean getJavascript(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getBoolean(KEY_JS, true); + } + + public static boolean getLocation(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getBoolean(KEY_LOCATION, true); + } + + public static boolean getCookie(Context context) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + return prefs.getBoolean(KEY_COOKIE, true); + } +} diff --git a/app/src/main/java/org/lineageos/jelly/utils/UiUtils.java b/app/src/main/java/org/lineageos/jelly/utils/UiUtils.java new file mode 100644 index 0000000..9fa5f0a --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/utils/UiUtils.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.utils; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.support.v4.content.ContextCompat; +import android.support.v4.graphics.ColorUtils; +import android.support.v7.graphics.Palette; +import android.util.TypedValue; + +import org.lineageos.jelly.R; + +public final class UiUtils { + + private UiUtils() { + } + + public static boolean isColorLight(int color) { + int red = Color.red(color); + int green = Color.green(color); + int blue = Color.blue(color); + + float hsl[] = new float[3]; + ColorUtils.RGBToHSL(red, green, blue, hsl); + return hsl[2] > 0.5f; + } + + public static int getColor(Context context, Bitmap bitmap, boolean incognito) { + Palette palette = Palette.from(bitmap).generate(); + int primary = ContextCompat.getColor(context, R.color.colorPrimary); + int alternative = ContextCompat.getColor(context, R.color.colorIncognito); + return incognito ? + palette.getMutedColor(alternative) : palette.getVibrantColor(primary); + } + + public static Bitmap getShortcutIcon(Context context, Bitmap bitmap) { + Bitmap out = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), + Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(out); + int color = getColor(context, bitmap, false); + Paint paint = new Paint(); + Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getWidth()); + float radius = bitmap.getWidth() / 2; + paint.setAntiAlias(true); + paint.setColor(color); + canvas.drawARGB(0, 0, 0, 0); + canvas.drawCircle(radius, radius, radius, paint); + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); + canvas.drawBitmap(bitmap, rect, rect, paint); + return Bitmap.createScaledBitmap(out, 192, 192, true); + } + + public static int getPositionInTime(long timeMilliSec) { + long diff = System.currentTimeMillis() - timeMilliSec; + + long hour = 1000 * 60 * 60; + long day = hour * 24; + long week = day * 7; + long month = day * 30; + + return hour > diff ? 0 : day > diff ? 1 : week > diff ? 2 : month > diff ? 3 : 4; + } + + public static float dpToPx(Resources res, int dp) { + return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics()); + } +} diff --git a/app/src/main/java/org/lineageos/jelly/utils/UrlUtils.java b/app/src/main/java/org/lineageos/jelly/utils/UrlUtils.java new file mode 100644 index 0000000..350a5ac --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/utils/UrlUtils.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.utils; + +import android.util.Log; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.regex.Pattern; + +public final class UrlUtils { + public static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile( + "(?i)" + // switch on case insensitive matching + "(" + // begin group for schema + "(?:http|https|file|chrome):\\/\\/" + + "|(?:inline|data|about|javascript):" + + ")" + + "(.*)" + ); + private static final String TAG = UrlUtils.class.getSimpleName(); + + private UrlUtils() { + } + + public static String fixUrl(String inUrl) { + inUrl = inUrl.toLowerCase(); + int colon = inUrl.indexOf(':'); + boolean allLower = true; + for (int index = 0; index < colon; index++) { + char ch = inUrl.charAt(index); + if (!Character.isLetter(ch)) { + break; + } + allLower &= Character.isLowerCase(ch); + if (index == colon - 1 && !allLower) { + inUrl = inUrl.substring(0, colon).toLowerCase() + + inUrl.substring(colon); + } + } + if (inUrl.startsWith("http://") || inUrl.startsWith("https://")) + return inUrl; + if (inUrl.startsWith("http:") || + inUrl.startsWith("https:")) { + if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) { + inUrl = inUrl.replaceFirst("/", "//"); + } else inUrl = inUrl.replaceFirst(":", "://"); + } + return inUrl; + } + + /** + * Formats a launch-able uri out of the template uri by replacing the template parameters with + * actual values. + */ + public static String getFormattedUri(String templateUri, String query) { + if (templateUri.isEmpty()) { + return null; + } + + // Encode the query terms in the UTF-8 encoding + try { + return templateUri.replace("{searchTerms}", URLEncoder.encode(query, "UTF-8")); + } catch (UnsupportedEncodingException e) { + Log.e(TAG, "Exception occurred when encoding query " + query + " to UTF-8"); + return null; + } + } + + +} diff --git a/app/src/main/java/org/lineageos/jelly/webview/ChromeClient.java b/app/src/main/java/org/lineageos/jelly/webview/ChromeClient.java new file mode 100644 index 0000000..1f7c576 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/webview/ChromeClient.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.webview; + +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.view.View; +import android.webkit.GeolocationPermissions; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import android.widget.EditText; +import android.widget.ProgressBar; +import android.widget.Toast; + +import org.lineageos.jelly.MainActivity; +import org.lineageos.jelly.R; +import org.lineageos.jelly.history.HistoryDatabaseHandler; +import org.lineageos.jelly.history.HistoryItem; + + +class ChromeClient extends WebChromeClient { + + private final Context mContext; + private final HistoryDatabaseHandler mHistoryHandler; + private final boolean mIncognito; + + private EditText mEditText; + private ProgressBar mProgressBar; + + ChromeClient(Context context, boolean incognito) { + super(); + mContext = context; + mHistoryHandler = new HistoryDatabaseHandler(context); + mIncognito = incognito; + } + + @Override + public void onProgressChanged(WebView view, int progress) { + mProgressBar.setVisibility(progress == 100 ? View.INVISIBLE : View.VISIBLE); + mProgressBar.setProgress(progress == 100 ? 0 : progress); + super.onProgressChanged(view, progress); + } + + @Override + public void onReceivedTitle(WebView view, String title) { + mEditText.setText(view.getUrl()); + mHistoryHandler.addItem(new HistoryItem(title, view.getUrl())); + } + + @Override + public void onReceivedIcon(WebView view, Bitmap icon) { + ((MainActivity) mContext).setColor(icon, mIncognito); + } + + @Override + public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> path, + FileChooserParams params) { + Intent intent = params.createIntent(); + try { + ((MainActivity) mContext).startActivityForResult(intent, MainActivity.FILE_CHOOSER_REQ); + } catch (ActivityNotFoundException e) { + Toast.makeText(mContext, mContext.getString(R.string.error_no_activity_found), + Toast.LENGTH_LONG).show(); + return false; + } + return true; + } + + @Override + public void onGeolocationPermissionsShowPrompt(String origin, + GeolocationPermissions.Callback callback) { + MainActivity activity = ((MainActivity) mContext); + if (activity.hasLocationPermission()) { + activity.requestLocationPermission(); + } else { + callback.invoke(origin, true, false); + } + } + + void bindEditText(EditText editText) { + mEditText = editText; + } + + void bindProgressBar(ProgressBar progressBar) { + mProgressBar = progressBar; + } +} diff --git a/app/src/main/java/org/lineageos/jelly/webview/WebClient.java b/app/src/main/java/org/lineageos/jelly/webview/WebClient.java new file mode 100644 index 0000000..43230ab --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/webview/WebClient.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.webview; + +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.support.design.widget.Snackbar; +import android.webkit.WebResourceRequest; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import org.lineageos.jelly.R; + +class WebClient extends WebViewClient { + + WebClient() { + super(); + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + String url = request.getUrl().toString(); + Context context = view.getContext(); + if (!url.startsWith("http")) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(request.getUrl()); + context.startActivity(intent); + } catch (ActivityNotFoundException e) { + Snackbar.make(view, context.getString(R.string.error_no_activity_found), + Snackbar.LENGTH_LONG).show(); + } + return true; + } + + return false; + } + +} diff --git a/app/src/main/java/org/lineageos/jelly/webview/WebViewExt.java b/app/src/main/java/org/lineageos/jelly/webview/WebViewExt.java new file mode 100644 index 0000000..ec09df9 --- /dev/null +++ b/app/src/main/java/org/lineageos/jelly/webview/WebViewExt.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2017 The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.jelly.webview; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.util.AttributeSet; +import android.util.Patterns; +import android.view.View; +import android.webkit.URLUtil; +import android.webkit.WebView; +import android.widget.EditText; +import android.widget.ProgressBar; + +import org.lineageos.jelly.MainActivity; +import org.lineageos.jelly.utils.PrefsUtils; +import org.lineageos.jelly.utils.UrlUtils; + +public class WebViewExt extends WebView { + + private final Context mContext; + + public WebViewExt(Context context) { + super(context); + mContext = context; + setup(); + } + + public WebViewExt(Context context, AttributeSet attrs) { + super(context, attrs); + mContext = context; + setup(); + } + + public WebViewExt(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mContext = context; + setup(); + } + + @Override + public void loadUrl(String url) { + // Try to add http prefix + if (!url.startsWith("http")) { + String withHttp = "http://" + url; + if ((Patterns.WEB_URL.matcher(withHttp).matches() || + UrlUtils.ACCEPTED_URI_SCHEMA.matcher(withHttp).matches()) && + withHttp.contains(".")) { + super.loadUrl(withHttp); + return; + } + } + + // http url + String query = UrlUtils.fixUrl(url).trim(); + if (Patterns.WEB_URL.matcher(query).matches() || + UrlUtils.ACCEPTED_URI_SCHEMA.matcher(query).matches() || + query.isEmpty()) { + super.loadUrl(url); + return; + } + + // Query + String baseUrl = PrefsUtils.getSearchEngine(mContext); + super.loadUrl(UrlUtils.getFormattedUri(baseUrl, query)); + } + + private void setup() { + getSettings().setJavaScriptEnabled(PrefsUtils.getJavascript(mContext)); + getSettings().setGeolocationEnabled(PrefsUtils.getLocation(mContext)); + getSettings().setBuiltInZoomControls(true); + getSettings().setDisplayZoomControls(false); + + setWebViewClient(new WebClient()); + + setOnLongClickListener(new OnLongClickListener() { + boolean shouldAllowDownload; + + @Override + public boolean onLongClick(View v) { + HitTestResult result = getHitTestResult(); + switch (result.getType()) { + case HitTestResult.IMAGE_TYPE: + case HitTestResult.SRC_IMAGE_ANCHOR_TYPE: + shouldAllowDownload = true; + case HitTestResult.SRC_ANCHOR_TYPE: + ((MainActivity) mContext).showSheetMenu(result.getExtra(), + shouldAllowDownload); + shouldAllowDownload = false; + return true; + } + return false; + } + }); + + setDownloadListener((url, userAgent, contentDescription, mimeType, contentLength) -> + ((MainActivity) mContext).downloadFileAsk(url, + URLUtil.guessFileName(url, contentDescription, mimeType))); + } + + public void init(Context context, EditText editText, + ProgressBar progressBar, boolean incognito) { + ChromeClient chromeClient = new ChromeClient(context, incognito); + chromeClient.bindEditText(editText); + chromeClient.bindProgressBar(progressBar); + setWebChromeClient(chromeClient); + } + + public Bitmap getSnap() { + measure(MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED), + MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); + layout(0, 0, getMeasuredWidth(), getMeasuredHeight()); + setDrawingCacheEnabled(true); + buildDrawingCache(); + int size = getMeasuredWidth() > getMeasuredHeight() ? + getMeasuredHeight() : getMeasuredWidth(); + Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + Paint paint = new Paint(); + int height = bitmap.getHeight(); + canvas.drawBitmap(bitmap, 0, height, paint); + draw(canvas); + return bitmap; + } + +} diff --git a/app/src/main/res/drawable/empty_background.xml b/app/src/main/res/drawable/empty_background.xml new file mode 100644 index 0000000..979810d --- /dev/null +++ b/app/src/main/res/drawable/empty_background.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> + + <solid android:color="@color/empty_background" /> + <size + android:width="120dp" + android:height="120dp" /> + +</shape> diff --git a/app/src/main/res/drawable/ic_back.xml b/app/src/main/res/drawable/ic_back.xml new file mode 100644 index 0000000..9a49b5c --- /dev/null +++ b/app/src/main/res/drawable/ic_back.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml new file mode 100644 index 0000000..20fa211 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_download.xml b/app/src/main/res/drawable/ic_download.xml new file mode 100644 index 0000000..ef4758f --- /dev/null +++ b/app/src/main/res/drawable/ic_download.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_favorite.xml b/app/src/main/res/drawable/ic_favorite.xml new file mode 100644 index 0000000..0c71c6c --- /dev/null +++ b/app/src/main/res/drawable/ic_favorite.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_favorite_add.xml b/app/src/main/res/drawable/ic_favorite_add.xml new file mode 100644 index 0000000..956f6db --- /dev/null +++ b/app/src/main/res/drawable/ic_favorite_add.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M 8,13 L 11,13 L 11,16 L 13,16 L 13,13 L 16,13 L 16,11 L 13,11 L 13,8 L 11,8 L 11,11 L 8,11 L 8,13 M16.5,3c-1.74,0 -3.41,0.81 -4.5,2.09C10.91,3.81 9.24,3 7.5,3 4.42,3 2,5.42 2,8.5c0,3.78 3.4,6.86 8.55,11.54L12,21.35l1.45,-1.32C18.6,15.36 22,12.28 22,8.5 22,5.42 19.58,3 16.5,3zM12.1,18.55l-0.1,0.1 -0.1,-0.1C7.14,14.24 4,11.39 4,8.5 4,6.5 5.5,5 7.5,5c1.54,0 3.04,0.99 3.57,2.36h1.87C13.46,5.99 14.96,5 16.5,5c2,0 3.5,1.5 3.5,3.5 0,2.89 -3.14,5.74 -7.9,10.05z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_history.xml b/app/src/main/res/drawable/ic_history.xml new file mode 100644 index 0000000..2b4d8bc --- /dev/null +++ b/app/src/main/res/drawable/ic_history.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_incognito.xml b/app/src/main/res/drawable/ic_incognito.xml new file mode 100644 index 0000000..e489464 --- /dev/null +++ b/app/src/main/res/drawable/ic_incognito.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M12,3C9.31,3 7.41,4.22 7.41,4.22L6,9H18L16.59,4.22C16.59,4.22 14.69,3 12,3M12,11C9.27,11 5.39,11.54 5.13,11.59C4.09,11.87 3.25,12.15 2.59,12.41C1.58,12.75 1,13 1,13H23C23,13 22.42,12.75 21.41,12.41C20.75,12.15 19.89,11.87 18.84,11.59C18.84,11.59 14.82,11 12,11M7.5,14A3.5,3.5 0 0,0 4,17.5A3.5,3.5 0 0,0 7.5,21A3.5,3.5 0 0,0 11,17.5C11,17.34 11,17.18 10.97,17.03C11.29,16.96 11.63,16.9 12,16.91C12.37,16.91 12.71,16.96 13.03,17.03C13,17.18 13,17.34 13,17.5A3.5,3.5 0 0,0 16.5,21A3.5,3.5 0 0,0 20,17.5A3.5,3.5 0 0,0 16.5,14C15.03,14 13.77,14.9 13.25,16.19C12.93,16.09 12.55,16 12,16C11.45,16 11.07,16.09 10.75,16.19C10.23,14.9 8.97,14 7.5,14M7.5,15A2.5,2.5 0 0,1 10,17.5A2.5,2.5 0 0,1 7.5,20A2.5,2.5 0 0,1 5,17.5A2.5,2.5 0 0,1 7.5,15M16.5,15A2.5,2.5 0 0,1 19,17.5A2.5,2.5 0 0,1 16.5,20A2.5,2.5 0 0,1 14,17.5A2.5,2.5 0 0,1 16.5,15Z" /> +</vector> + diff --git a/app/src/main/res/drawable/ic_menu.xml b/app/src/main/res/drawable/ic_menu.xml new file mode 100644 index 0000000..330ebbb --- /dev/null +++ b/app/src/main/res/drawable/ic_menu.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_new_tab.xml b/app/src/main/res/drawable/ic_new_tab.xml new file mode 100644 index 0000000..c65ad97 --- /dev/null +++ b/app/src/main/res/drawable/ic_new_tab.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_refresh.xml b/app/src/main/res/drawable/ic_refresh.xml new file mode 100644 index 0000000..771eda2 --- /dev/null +++ b/app/src/main/res/drawable/ic_refresh.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml new file mode 100644 index 0000000..2fe40e8 --- /dev/null +++ b/app/src/main/res/drawable/ic_settings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_share.xml b/app/src/main/res/drawable/ic_share.xml new file mode 100644 index 0000000..ae96135 --- /dev/null +++ b/app/src/main/res/drawable/ic_share.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/> +</vector> diff --git a/app/src/main/res/drawable/ic_shortcut.xml b/app/src/main/res/drawable/ic_shortcut.xml new file mode 100644 index 0000000..96d6630 --- /dev/null +++ b/app/src/main/res/drawable/ic_shortcut.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@color/menu_icon" + android:pathData="M16,8h-2v3h-3v2h3v3h2v-3h3v-2h-3zM2,12c0,-2.79 1.64,-5.2 4.01,-6.32L6.01,3.52C2.52,4.76 0,8.09 0,12s2.52,7.24 6.01,8.48v-2.16C3.64,17.2 2,14.79 2,12zM15,3c-4.96,0 -9,4.04 -9,9s4.04,9 9,9 9,-4.04 9,-9 -4.04,-9 -9,-9zM15,19c-3.86,0 -7,-3.14 -7,-7s3.14,-7 7,-7 7,3.14 7,7 -3.14,7 -7,7z"/> +</vector> diff --git a/app/src/main/res/layout/activity_favorites.xml b/app/src/main/res/layout/activity_favorites.xml new file mode 100644 index 0000000..89e5104 --- /dev/null +++ b/app/src/main/res/layout/activity_favorites.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/coordinator_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true"> + + <android.support.v7.widget.Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="?colorPrimary" /> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingTop="?actionBarSize"> + + <android.support.v7.widget.RecyclerView + android:id="@+id/favorite_list" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingEnd="12dp" + android:paddingStart="12dp" + android:scrollbars="vertical" /> + + <LinearLayout + android:id="@+id/favorite_empty_layout" + style="@style/AppTheme.EmptyLayout" + tools:ignore="UseCompoundDrawables"> + + <ImageView + style="@style/AppTheme.EmptyImage" + android:src="@drawable/ic_favorite" + android:tint="@color/empty_image" /> + + <TextView + style="@style/AppTheme.EmptyText" + android:text="@string/favorite_empty" /> + </LinearLayout> + </RelativeLayout> +</android.support.design.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/activity_history.xml b/app/src/main/res/layout/activity_history.xml new file mode 100644 index 0000000..6583337 --- /dev/null +++ b/app/src/main/res/layout/activity_history.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/coordinator_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true"> + + <android.support.v7.widget.Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="?colorPrimary" /> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingTop="?actionBarSize"> + + <android.support.v7.widget.RecyclerView + android:id="@+id/history_list" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scrollbars="vertical" /> + + <LinearLayout + android:id="@+id/history_empty_layout" + style="@style/AppTheme.EmptyLayout" + tools:ignore="UseCompoundDrawables"> + + <ImageView + style="@style/AppTheme.EmptyImage" + android:src="@drawable/ic_history" + android:tint="@color/empty_image" /> + + <TextView + style="@style/AppTheme.EmptyText" + android:text="@string/history_empty" /> + </LinearLayout> + </RelativeLayout> +</android.support.design.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..3db09c4 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/coordinator_layout" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <android.support.design.widget.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:theme="@style/AppTheme.AppBarOverlay"> + + <android.support.v7.widget.Toolbar + android:id="@+id/toolbar" + style="@style/AppTheme.ToolbarTheme" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimaryDark" + app:popupTheme="@style/AppTheme.PopupOverlay"> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ProgressBar + android:id="@+id/load_progress" + style="@style/Widget.AppCompat.ProgressBar.Horizontal" + android:layout_width="match_parent" + android:layout_height="2dp" + android:layout_alignParentBottom="true" + android:max="100" + android:paddingTop="2dp" + android:progress="54" /> + + <include + layout="@layout/search_bar" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_above="@id/load_progress" /> + + </RelativeLayout> + </android.support.v7.widget.Toolbar> + </android.support.design.widget.AppBarLayout> + + <android.support.v4.widget.SwipeRefreshLayout + android:id="@+id/swipe_refresh" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginTop="?actionBarSize"> + + <org.lineageos.jelly.webview.WebViewExt + android:id="@+id/web_view" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + </android.support.v4.widget.SwipeRefreshLayout> +</android.support.design.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml new file mode 100644 index 0000000..e664677 --- /dev/null +++ b/app/src/main/res/layout/activity_settings.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <android.support.v7.widget.Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="?colorPrimary" /> + + <fragment + android:name="org.lineageos.jelly.SettingsActivity$MyPreferenceFragment" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@+id/toolbar" + android:tag="org.lineageos.jelly.SettingsActivity$MyPreferenceFragment" /> +</RelativeLayout> diff --git a/app/src/main/res/layout/dialog_favorite_edit.xml b/app/src/main/res/layout/dialog_favorite_edit.xml new file mode 100644 index 0000000..9a9dfea --- /dev/null +++ b/app/src/main/res/layout/dialog_favorite_edit.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:paddingBottom="8dp" + android:paddingEnd="24dp" + android:paddingStart="24dp" + android:paddingTop="16dp"> + + <android.support.design.widget.TextInputLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="8dp"> + + <org.lineageos.jelly.ui.EditTextExt + android:id="@+id/favorite_edit_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/favorite_edit_title" /> + </android.support.design.widget.TextInputLayout> + + <android.support.design.widget.TextInputLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:errorTextAppearance="@string/favorite_edit_error"> + + <org.lineageos.jelly.ui.EditTextExt + android:id="@+id/favorite_edit_url" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/favorite_edit_url" + android:inputType="textUri" /> + </android.support.design.widget.TextInputLayout> + +</LinearLayout> diff --git a/app/src/main/res/layout/item_favorite.xml b/app/src/main/res/layout/item_favorite.xml new file mode 100644 index 0000000..6e27d8b --- /dev/null +++ b/app/src/main/res/layout/item_favorite.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/row_favorite_card" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="4dp" + android:foreground="?selectableItemBackground" + android:orientation="vertical" + app:contentPadding="8dp"> + + <TextView + android:id="@+id/row_favorite_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:ellipsize="end" + android:maxLines="2" + android:paddingBottom="12dp" + android:paddingTop="12dp" + android:textAlignment="center" + android:textSize="18sp" /> + +</android.support.v7.widget.CardView> diff --git a/app/src/main/res/layout/item_history.xml b/app/src/main/res/layout/item_history.xml new file mode 100644 index 0000000..1a750aa --- /dev/null +++ b/app/src/main/res/layout/item_history.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/row_history_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:foreground="?selectableItemBackground" + android:gravity="center_vertical" + android:minHeight="60dp" + android:orientation="vertical" + android:paddingEnd="16dp" + android:paddingStart="16dp"> + + <TextView + android:id="@+id/row_history_title" + style="@android:style/TextAppearance.Medium" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:maxLines="1" /> + + <TextView + android:id="@+id/row_history_summary" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + +</LinearLayout> diff --git a/app/src/main/res/layout/search_bar.xml b/app/src/main/res/layout/search_bar.xml new file mode 100644 index 0000000..cead495 --- /dev/null +++ b/app/src/main/res/layout/search_bar.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:paddingBottom="4dp" + android:paddingEnd="16dp" + android:paddingStart="16dp" + android:paddingTop="4dp"> + + <!-- Dummy view to catch focus --> + <View + android:layout_width="0dp" + android:layout_height="0dp" + android:focusable="true" + android:focusableInTouchMode="true" /> + + <android.support.v7.widget.CardView + android:layout_width="match_parent" + android:layout_height="match_parent" + app:cardBackgroundColor="@color/cardview_light_background" + app:cardElevation="4dp" + app:contentPadding="2dp"> + + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ImageButton + android:id="@+id/search_menu" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_alignParentEnd="true" + android:adjustViewBounds="true" + android:background="?selectableItemBackgroundBorderless" + android:padding="8dp" + android:src="@drawable/ic_menu" /> + + <org.lineageos.jelly.ui.EditTextExt + android:id="@+id/url_bar" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alignParentStart="true" + android:layout_toStartOf="@id/search_menu" + android:background="@null" + android:fadingEdge="vertical" + android:imeOptions="actionSearch" + android:inputType="textUri" + android:maxLines="1" + android:nextFocusLeft="@id/url_bar" + android:nextFocusUp="@id/url_bar" + android:paddingStart="4dp" + android:textColor="@android:color/black" + tools:ignore="RtlSymmetry" /> + </RelativeLayout> + </android.support.v7.widget.CardView> +</RelativeLayout> diff --git a/app/src/main/res/layout/sheet_actions.xml b/app/src/main/res/layout/sheet_actions.xml new file mode 100644 index 0000000..c0d41c4 --- /dev/null +++ b/app/src/main/res/layout/sheet_actions.xml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="180dp" + android:orientation="vertical" + app:layout_behavior="android.support.design.widget.BottomSheetBehavior" + tools:ignore="UseCompoundDrawables"> + + <LinearLayout + android:id="@+id/sheet_new_tab" + style="@style/AppTheme.BottomSheetLayout"> + + <ImageView + style="@style/AppTheme.BottomSheetIcon" + android:src="@drawable/ic_new_tab" /> + + <TextView + style="@style/AppTheme.BottomSheetText" + android:text="@string/menu_in_new_tab" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/sheet_share" + style="@style/AppTheme.BottomSheetLayout"> + + <ImageView + style="@style/AppTheme.BottomSheetIcon" + android:src="@drawable/ic_share" /> + + <TextView + style="@style/AppTheme.BottomSheetText" + android:text="@string/menu_share" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/sheet_favourite" + style="@style/AppTheme.BottomSheetLayout"> + + <ImageView + style="@style/AppTheme.BottomSheetIcon" + app:srcCompat="@drawable/ic_favorite_add" /> + + <TextView + style="@style/AppTheme.BottomSheetText" + android:text="@string/menu_fav_add" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/sheet_download" + style="@style/AppTheme.BottomSheetLayout" + android:visibility="gone"> + + <ImageView + style="@style/AppTheme.BottomSheetIcon" + app:srcCompat="@drawable/ic_download" /> + + <TextView + style="@style/AppTheme.BottomSheetText" + android:text="@string/menu_download" /> + </LinearLayout> +</LinearLayout> diff --git a/app/src/main/res/menu/menu_history.xml b/app/src/main/res/menu/menu_history.xml new file mode 100644 index 0000000..890681c --- /dev/null +++ b/app/src/main/res/menu/menu_history.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <item + android:id="@+id/menu_history_delete" + android:icon="@drawable/ic_delete" + android:title="@string/history_delete_title" + app:showAsAction="ifRoom" /> +</menu> diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml new file mode 100644 index 0000000..4557a73 --- /dev/null +++ b/app/src/main/res/menu/menu_main.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/menu_new" + android:icon="@drawable/ic_new_tab" + android:title="@string/menu_new_tab" + app:showAsAction="never" /> + <item + android:id="@+id/menu_incognito" + android:icon="@drawable/ic_incognito" + android:title="@string/menu_incognito" + app:showAsAction="never" /> + <item + android:id="@+id/menu_reload" + android:icon="@drawable/ic_refresh" + android:title="@string/menu_reload" + app:showAsAction="never" /> + <item + android:id="@+id/menu_add_favorite" + android:icon="@drawable/ic_favorite_add" + android:title="@string/menu_fav_add" + app:showAsAction="never" /> + <item + android:id="@+id/menu_share" + android:icon="@drawable/ic_share" + android:title="@string/menu_share" + app:showAsAction="never" /> + <item + android:id="@+id/menu_favorite" + android:icon="@drawable/ic_favorite" + android:title="@string/menu_favorites" + app:showAsAction="never" /> + <item + android:id="@+id/menu_history" + android:icon="@drawable/ic_history" + android:title="@string/menu_history" + app:showAsAction="never" /> + <item + android:id="@+id/menu_shortcut" + android:icon="@drawable/ic_shortcut" + android:title="@string/menu_shortcut" + app:showAsAction="never" /> + <item + android:id="@+id/menu_settings" + android:icon="@drawable/ic_settings" + android:title="@string/menu_settings" + app:showAsAction="never" /> +</menu> diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..d9dfdb9 --- /dev/null +++ b/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..09e1444 --- /dev/null +++ b/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..a61cc67 --- /dev/null +++ b/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..66fd773 --- /dev/null +++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..a7e5479 --- /dev/null +++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..5909177 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <color name="colorPrimary">#fafafa</color> + <color name="colorPrimaryDark">#E0E0E0</color> + <color name="colorAccent">#FF4081</color> + + <color name="colorIncognito">#000b4d</color> + + <color name="menu_icon">#333333</color> + + <color name="empty_image">#b1b1b1</color> + <color name="empty_background">#efefef</color> + <color name="empty_text">@color/empty_image</color> + + <color name="history_last_hour">#fafafa</color> + <color name="history_today">#f6f6f6</color> + <color name="history_this_week">#f0f0f0</color> + <color name="history_this_month">#eeeeee</color> + <color name="history_earlier">#e5e5e5</color> +</resources> diff --git a/app/src/main/res/values/search_engines.xml b/app/src/main/res/values/search_engines.xml new file mode 100644 index 0000000..ee8a428 --- /dev/null +++ b/app/src/main/res/values/search_engines.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + + <string-array name="pref_search_engine_entries" translatable="false"> + <item>Baidu</item> + <item>Bing</item> + <item>DuckDuckGo</item> + <item>Google</item> + <item>Yahoo</item> + </string-array> + + <string-array name="pref_search_engine_entryvalues" translatable="false"> + <item>https://www.baidu.com/s?wd={searchTerms}</item> + <item>https://www.bing.com/search?q={searchTerms}</item> + <item>https://duckduckgo.com/?q={searchTerms}</item> + <item>https://encrypted.google.com/search?q={searchTerms}</item> + <item>https://search.yahoo.com/p={searchTerms}</item> + </string-array> +</resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..523055d --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <string name="app_name">Browser</string> + + <!-- Menu action: create new tab --> + <string name="menu_new_tab">New tab</string> + <!-- Menu action: create new incognito tab --> + <string name="menu_incognito">Incognito tab</string> + <!-- Menu action: reload current page --> + <string name="menu_reload">Reload</string> + <!-- Menu action: add current page to favorites --> + <string name="menu_fav_add">Add to favorites</string> + <!-- Menu action: share current page --> + <string name="menu_share">Share</string> + <!-- Menu action: show favorites list --> + <string name="menu_favorites">Favorites</string> + <!-- Menu action: show history list --> + <string name="menu_history">History</string> + <!-- Menu action: add shortcut of the current page to the launcher --> + <string name="menu_shortcut">Add shortcut</string> + <!-- Menu action: show settings --> + <string name="menu_settings">Settings</string> + <!-- Menu action: download selected file / image --> + <string name="menu_download">Download</string> + <!-- Menu action: open selected link in a new tab --> + <string name="menu_in_new_tab">Open in new tab</string> + + <!-- Dialog action: dismiss --> + <string name="dismiss">Dismiss</string> + + <!-- Download dialog: title --> + <string name="download_title">Download file</string> + <!-- Download dialog: message --> + <string name="download_message">Do you want to download %1$s to the sdcard?</string> + <!-- Download dialog: button that starts the download --> + <string name="download_positive">Download</string> + + <!-- Permission error dialog: title --> + <string name="permission_error_title">Permission error</string> + <!-- Permission error dialog: message for denied storage access--> + <string name="permission_error_storage">Browser needs storage access to download files. Please grant it to save files from the web</string> + <!-- Permission error dialog: button that triggers permission request again --> + <string name="permission_error_ask_again">Ask again</string> + <!-- Permission error snackBar: the permission has been denied until user enables it in settings --> + <string name="permission_error_forever">Permission denied forever. Please grant it in settings</string> + + <!-- Shortcut: the current webPage has been added to the launcher --> + <string name="shortcut_added">Added to the home screen</string> + + <!-- Settings: title --> + <string name="settings_title">Settings</string> + <!-- Settings: search engine preference title --> + <string name="pref_search_engine">Search engine</string> + <!-- Settings: home page preference title --> + <string name="pref_start_page">Home page</string> + <!-- Settings: select home page dialog title --> + <string name="pref_start_page_dialog_title">Select home page</string> + <!-- Settings: select home page dialog message --> + <string name="pref_start_page_dialog_message">Write the home page url</string> + <!-- Settings: privacy and security category --> + <string name="pref_privacy_security">Privacy & security</string> + <!-- Settings: lookLock title --> + <string name="pref_looklock_title">LookLock</string> + <!-- Settings: lookLock summary --> + <string name="pref_looklock_summary">Prevent other apps from reading Browser\'s content</string> + <!-- Settings: javascript preference title --> + <string name="pref_js_title">Javascript</string> + <!-- Settings: javascript preference summary --> + <string name="pref_js_summary">Enable javascript</string> + <!-- Settings: location preference title --> + <string name="pref_location_title">Location</string> + <!-- Settings: location preference summary. Note that this doesn't allow permission access to the websites, but just allows the possibility of requesting access to it --> + <string name="pref_location_summary">Allow websites to request access to your location</string> + <!-- Settings: cookie preference title --> + <string name="pref_cookie_title">Cookies</string> + <!-- Settings: cookie preference summary --> + <string name="pref_cookie_summary">Allow websites to save and load cookies</string> + <!-- Settings: advanced share preference title --> + <string name="pref_screenshot_snap_title">Advanced share</string> + <!-- Settings: advanced share preference summary --> + <string name="pref_screenshot_snap_summary">Share preview of the shared WebPage</string> + + <!-- History: title --> + <string name="history_title">History</string> + <!-- History: empty status text --> + <string name="history_empty">There\'s nothing here, browse on the internet to see your history here</string> + <!-- History: date format for items. EEEE = day (Monday), MMMM = month (January), yyyy = year (1970), HH = hour (12), mm = minutes (30) --> + <string name="history_date_format">EEEE MMMM dd yyyy, HH:mm</string> + <!-- History: delete history dialog title --> + <string name="history_delete_title">Clear history</string> + <!-- History: delete history dialog warning message --> + <string name="history_delete_message">You\'re going to delete all the history, this action cannot be undone. Do you want to proceed?</string> + <!-- History: delete history dialog button that erases all the history --> + <string name="history_delete_positive">Clear</string> + <!-- History: delete history "working" dialog--> + <string name="history_deleting_message">Clearing history\u2026</string> + + <!-- Favorite: title --> + <string name="favorite_title">Favorites</string> + <!-- Favorite: snackBar message shown when an url is added to favorites --> + <string name="favorite_added">Added to favorites</string> + <!-- Favorite: empty status text --> + <string name="favorite_empty">There\'s nothing here, add a favorite link to see it here</string> + <!-- Favorite: edit dialog title --> + <string name="favorite_edit_dialog_title">Edit favorite</string> + <!-- Favorite: edit dialog: title of the favorite --> + <string name="favorite_edit_title">Title</string> + <!-- Favorite: edit dialog: url of the favorite--> + <string name="favorite_edit_url">Url</string> + <!-- Favorite: edit dialog positive button that save changes --> + <string name="favorite_edit_positive">Edit</string> + <!-- Favorite: edit dialog button that deletes the selected favorite --> + <string name="favorite_edit_delete">Delete</string> + <!-- Favorite: edit dialog: invalid url error message --> + <string name="favorite_edit_error">Insert a valid url</string> + + <!-- No activity found to open the given url error --> + <string name="error_no_activity_found">No app can handle this link</string> + + <string translatable="false" name="default_search_engine">https://duckduckgo.com/?q={searchTerms}</string> + <string translatable="false" name="default_home_page">https://duckduckgo.com</string> +</resources> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..d7d63c3 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> + <item name="colorPrimary">@color/colorPrimary</item> + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> + <item name="colorAccent">@color/colorAccent</item> + <item name="android:windowLightStatusBar">true</item> + </style> + + <style name="AppTheme.NoActionBar"> + <item name="windowActionBar">false</item> + <item name="windowNoTitle">true</item> + </style> + + <style name="AppTheme.ToolbarTheme" parent="Widget.AppCompat.Toolbar"> + <item name="contentInsetStart">0dp</item> + </style> + + <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> + + <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> + + <style name="AppTheme.PopupMenuOverlapAnchor"> + <item name="android:overlapAnchor">true</item> + <item name="android:dropDownVerticalOffset">0dp</item> + <item name="android:dropDownHorizontalOffset">0dp</item> + </style> + + <style name="AppTheme.BottomSheetLayout"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">60dp</item> + <item name="android:clickable">true</item> + <item name="android:focusable">true</item> + <item name="android:foreground">?android:attr/selectableItemBackground</item> + <item name="android:orientation">horizontal</item> + <item name="android:padding">16dp</item> + </style> + + <style name="AppTheme.BottomSheetIcon"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">match_parent</item> + <item name="android:contentDescription">@null</item> + <item name="android:tint">@color/menu_icon</item> + </style> + + <style name="AppTheme.BottomSheetText"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_gravity">center</item> + <item name="android:layout_marginStart">16dp</item> + </style> + + <style name="AppTheme.EmptyLayout"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">match_parent</item> + <item name="android:gravity">center</item> + <item name="android:orientation">vertical</item> + <item name="android:visibility">gone</item> + </style> + + <style name="AppTheme.EmptyImage"> + <item name="android:layout_width">120dp</item> + <item name="android:layout_height">120dp</item> + <item name="android:background">@drawable/empty_background</item> + <item name="android:padding">8dp</item> + <item name="android:scaleType">fitXY</item> + </style> + + <style name="AppTheme.EmptyText"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:paddingEnd">64dp</item> + <item name="android:paddingStart">64dp</item> + <item name="android:paddingTop">19dp</item> + <item name="android:textAlignment">center</item> + <item name="android:textColor">@color/empty_text</item> + <item name="android:textSize">14sp</item> + </style> +</resources> diff --git a/app/src/main/res/xml/backup_descriptor.xml b/app/src/main/res/xml/backup_descriptor.xml new file mode 100644 index 0000000..2084478 --- /dev/null +++ b/app/src/main/res/xml/backup_descriptor.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<full-backup-content> + <!-- Shared preferences --> + <include + domain="sharedpref" + path="org.lineageos.jelly_preferences.xml" /> + + <!-- Databases --> + <include + domain="database" + path="HistoryDatabase" /> + <include + domain="database" + path="FavoriteDatabase" /> +</full-backup-content> diff --git a/app/src/main/res/xml/file_provider.xml b/app/src/main/res/xml/file_provider.xml new file mode 100644 index 0000000..aa235e6 --- /dev/null +++ b/app/src/main/res/xml/file_provider.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<paths> + <cache-path + name="all_dirs" + path="." /> +</paths> diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml new file mode 100644 index 0000000..9205098 --- /dev/null +++ b/app/src/main/res/xml/settings.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2017 The LineageOS Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + + <ListPreference + android:defaultValue="@string/default_search_engine" + android:entries="@array/pref_search_engine_entries" + android:entryValues="@array/pref_search_engine_entryvalues" + android:key="key_search_engine" + android:summary="%s" + android:title="@string/pref_search_engine" /> + + <EditTextPreference + android:defaultValue="@string/default_home_page" + android:dialogMessage="@string/pref_start_page_dialog_message" + android:dialogTitle="@string/pref_start_page_dialog_title" + android:key="key_home_page" + android:title="@string/pref_start_page" /> + + <SwitchPreference + android:defaultValue="0" + android:key="key_advanced_share" + android:summary="@string/pref_screenshot_snap_summary" + android:title="@string/pref_screenshot_snap_title" /> + + <PreferenceCategory android:title="@string/pref_privacy_security"> + + <SwitchPreference + android:defaultValue="0" + android:key="key_looklock" + android:summary="@string/pref_looklock_summary" + android:title="@string/pref_looklock_title" /> + + <SwitchPreference + android:defaultValue="1" + android:key="key_javascript" + android:summary="@string/pref_js_summary" + android:title="@string/pref_js_title" /> + + <SwitchPreference + android:defaultValue="1" + android:key="key_location" + android:summary="@string/pref_location_summary" + android:title="@string/pref_location_title" /> + + <SwitchPreference + android:defaultValue="1" + android:key="key_cookie" + android:summary="@string/pref_cookie_summary" + android:title="@string/pref_cookie_title" /> + </PreferenceCategory> +</PreferenceScreen> diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..1ea4bd0 --- /dev/null +++ b/build.gradle @@ -0,0 +1,23 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.3.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..aac7c9b --- /dev/null +++ b/gradle.properties @@ -0,0 +1,17 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 0000000..13372ae --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..61f2322 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Apr 14 16:24:15 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..aec9973 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':app' |