Refactoring: Bookmarks as Fragment
1. Incognito mode in another process 2. Bookmarks as a Fragement using Otto 3. Initial bookmarks as fragment implementation
This commit is contained in:
parent
98f0daceaa
commit
3c9cd73bf0
@ -48,6 +48,7 @@ dependencies {
|
|||||||
compile 'com.android.support:design:23.0.0'
|
compile 'com.android.support:design:23.0.0'
|
||||||
compile 'com.android.support:recyclerview-v7:23.0.0'
|
compile 'com.android.support:recyclerview-v7:23.0.0'
|
||||||
compile 'org.jsoup:jsoup:1.8.1'
|
compile 'org.jsoup:jsoup:1.8.1'
|
||||||
|
compile 'com.squareup:otto:1.3.8'
|
||||||
// Only Lightning Plus needs the proxy libraries
|
// Only Lightning Plus needs the proxy libraries
|
||||||
lightningPlusCompile 'net.i2p.android:client:0.7'
|
lightningPlusCompile 'net.i2p.android:client:0.7'
|
||||||
lightningPlusCompile(project(':libnetcipher'))
|
lightningPlusCompile(project(':libnetcipher'))
|
||||||
|
@ -110,7 +110,8 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:theme="@style/Theme.DarkTheme"
|
android:theme="@style/Theme.DarkTheme"
|
||||||
android:windowSoftInputMode="stateHidden" >
|
android:windowSoftInputMode="stateHidden"
|
||||||
|
android:process=":incognito">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.INCOGNITO" />
|
<action android:name="android.intent.action.INCOGNITO" />
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ import android.graphics.drawable.ColorDrawable;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@ -65,7 +64,6 @@ import android.view.ViewGroup;
|
|||||||
import android.view.ViewGroup.LayoutParams;
|
import android.view.ViewGroup.LayoutParams;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.animation.AccelerateInterpolator;
|
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.Animation.AnimationListener;
|
import android.view.animation.Animation.AnimationListener;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
@ -86,26 +84,26 @@ import android.widget.FrameLayout;
|
|||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.TextView.OnEditorActionListener;
|
import android.widget.TextView.OnEditorActionListener;
|
||||||
import android.widget.VideoView;
|
import android.widget.VideoView;
|
||||||
|
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import acr.browser.lightning.R;
|
import acr.browser.lightning.R;
|
||||||
|
import acr.browser.lightning.bus.BookmarkEvents;
|
||||||
|
import acr.browser.lightning.bus.BrowserEvents;
|
||||||
|
import acr.browser.lightning.bus.BusProvider;
|
||||||
import acr.browser.lightning.constant.BookmarkPage;
|
import acr.browser.lightning.constant.BookmarkPage;
|
||||||
import acr.browser.lightning.constant.Constants;
|
import acr.browser.lightning.constant.Constants;
|
||||||
import acr.browser.lightning.constant.HistoryPage;
|
import acr.browser.lightning.constant.HistoryPage;
|
||||||
@ -133,9 +131,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
private DrawerLayout mDrawerLayout;
|
private DrawerLayout mDrawerLayout;
|
||||||
private FrameLayout mBrowserFrame;
|
private FrameLayout mBrowserFrame;
|
||||||
private FullscreenHolder mFullscreenContainer;
|
private FullscreenHolder mFullscreenContainer;
|
||||||
private ListView mDrawerListRight;
|
|
||||||
private RecyclerView mDrawerListLeft;
|
private RecyclerView mDrawerListLeft;
|
||||||
private LinearLayout mDrawerLeft, mDrawerRight, mUiLayout, mToolbarLayout;
|
private ViewGroup mDrawerLeft, mDrawerRight, mUiLayout, mToolbarLayout;
|
||||||
private RelativeLayout mSearchBar;
|
private RelativeLayout mSearchBar;
|
||||||
|
|
||||||
// List
|
// List
|
||||||
@ -147,12 +144,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
// Views
|
// Views
|
||||||
private AnimatedProgressBar mProgressBar;
|
private AnimatedProgressBar mProgressBar;
|
||||||
private AutoCompleteTextView mSearch;
|
private AutoCompleteTextView mSearch;
|
||||||
private ImageView mArrowImage, mBookmarkTitleImage, mBookmarkImage;
|
private ImageView mArrowImage;
|
||||||
private VideoView mVideoView;
|
private VideoView mVideoView;
|
||||||
private View mCustomView, mVideoProgressView;
|
private View mCustomView, mVideoProgressView;
|
||||||
|
|
||||||
// Adapter
|
// Adapter
|
||||||
private BookmarkViewAdapter mBookmarkAdapter;
|
|
||||||
private LightningViewAdapter mTabAdapter;
|
private LightningViewAdapter mTabAdapter;
|
||||||
private SearchAdapter mSearchAdapter;
|
private SearchAdapter mSearchAdapter;
|
||||||
|
|
||||||
@ -180,7 +176,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
private PreferenceManager mPreferences;
|
private PreferenceManager mPreferences;
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
private Bitmap mDefaultVideoPoster, mWebpageBitmap, mFolderBitmap;
|
private Bitmap mDefaultVideoPoster, mWebpageBitmap;
|
||||||
private final ColorDrawable mBackground = new ColorDrawable();
|
private final ColorDrawable mBackground = new ColorDrawable();
|
||||||
private Drawable mDeleteIcon, mRefreshIcon, mSearchIcon, mIcon;
|
private Drawable mDeleteIcon, mRefreshIcon, mSearchIcon, mIcon;
|
||||||
private DrawerArrowDrawable mArrowDrawable;
|
private DrawerArrowDrawable mArrowDrawable;
|
||||||
@ -196,7 +192,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(
|
private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(
|
||||||
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||||
|
|
||||||
abstract boolean isIncognito();
|
public abstract boolean isIncognito();
|
||||||
|
|
||||||
abstract void initializeTabs();
|
abstract void initializeTabs();
|
||||||
|
|
||||||
@ -241,11 +237,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
// Drawer stutters otherwise
|
// Drawer stutters otherwise
|
||||||
mDrawerLeft.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
mDrawerLeft.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||||
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
|
||||||
mDrawerRight = (LinearLayout) findViewById(R.id.right_drawer);
|
mDrawerRight = (ViewGroup) findViewById(R.id.right_drawer);
|
||||||
mDrawerRight.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
mDrawerRight.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||||
mDrawerListRight = (ListView) findViewById(R.id.right_drawer_list);
|
|
||||||
mBookmarkTitleImage = (ImageView) findViewById(R.id.starIcon);
|
|
||||||
mBookmarkTitleImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
|
|
||||||
ImageView tabTitleImage = (ImageView) findViewById(R.id.plusIcon);
|
ImageView tabTitleImage = (ImageView) findViewById(R.id.plusIcon);
|
||||||
tabTitleImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
|
tabTitleImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
|
||||||
|
|
||||||
@ -257,7 +250,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
mDrawerLayout.setDrawerListener(new DrawerLocker());
|
mDrawerLayout.setDrawerListener(new DrawerLocker());
|
||||||
|
|
||||||
mWebpageBitmap = ThemeUtils.getThemedBitmap(this, R.drawable.ic_webpage, mDarkTheme);
|
mWebpageBitmap = ThemeUtils.getThemedBitmap(this, R.drawable.ic_webpage, mDarkTheme);
|
||||||
mFolderBitmap = ThemeUtils.getThemedBitmap(this, R.drawable.ic_folder, mDarkTheme);
|
|
||||||
|
|
||||||
mHomepage = mPreferences.getHomepage();
|
mHomepage = mPreferences.getHomepage();
|
||||||
|
|
||||||
@ -283,11 +275,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
mDrawerListLeft.setAdapter(mTabAdapter);
|
mDrawerListLeft.setAdapter(mTabAdapter);
|
||||||
// mDrawerListLeft.setOnItemClickListener(new DrawerItemClickListener());
|
|
||||||
// mDrawerListLeft.setOnItemLongClickListener(new DrawerItemLongClickListener());
|
|
||||||
|
|
||||||
mDrawerListRight.setOnItemClickListener(new BookmarkItemClickListener());
|
|
||||||
mDrawerListRight.setOnItemLongClickListener(new BookmarkItemLongClickListener());
|
|
||||||
|
|
||||||
mHistoryDatabase = HistoryDatabase.getInstance(getApplicationContext());
|
mHistoryDatabase = HistoryDatabase.getInstance(getApplicationContext());
|
||||||
|
|
||||||
@ -324,12 +311,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
|
|
||||||
setupFrameLayoutButton(R.id.action_back, R.id.icon_back);
|
setupFrameLayoutButton(R.id.action_back, R.id.icon_back);
|
||||||
setupFrameLayoutButton(R.id.action_forward, R.id.icon_forward);
|
setupFrameLayoutButton(R.id.action_forward, R.id.icon_forward);
|
||||||
setupFrameLayoutButton(R.id.action_add_bookmark, R.id.icon_star);
|
|
||||||
setupFrameLayoutButton(R.id.action_toggle_desktop, R.id.icon_desktop);
|
setupFrameLayoutButton(R.id.action_toggle_desktop, R.id.icon_desktop);
|
||||||
setupFrameLayoutButton(R.id.action_reading, R.id.icon_reading);
|
setupFrameLayoutButton(R.id.action_reading, R.id.icon_reading);
|
||||||
|
|
||||||
mBookmarkImage = (ImageView) findViewById(R.id.icon_star);
|
|
||||||
|
|
||||||
// create the search EditText in the ToolBar
|
// create the search EditText in the ToolBar
|
||||||
mSearch = (AutoCompleteTextView) actionBar.getCustomView().findViewById(R.id.search);
|
mSearch = (AutoCompleteTextView) actionBar.getCustomView().findViewById(R.id.search);
|
||||||
mUntitledTitle = getString(R.string.untitled);
|
mUntitledTitle = getString(R.string.untitled);
|
||||||
@ -358,38 +342,11 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mBookmarkManager = BookmarkManager.getInstance(mActivity.getApplicationContext());
|
|
||||||
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
|
|
||||||
if (mBookmarkList.isEmpty() && mPreferences.getDefaultBookmarks()) {
|
|
||||||
for (String[] array : BookmarkManager.DEFAULT_BOOKMARKS) {
|
|
||||||
HistoryItem bookmark = new HistoryItem(array[0], array[1]);
|
|
||||||
if (mBookmarkManager.addBookmark(bookmark)) {
|
|
||||||
mBookmarkList.add(bookmark);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Collections.sort(mBookmarkList, new BookmarkManager.SortIgnoreCase());
|
|
||||||
mPreferences.setDefaultBookmarks(false);
|
|
||||||
}
|
|
||||||
mBookmarkAdapter = new BookmarkViewAdapter(mActivity, R.layout.bookmark_list_item,
|
|
||||||
mBookmarkList);
|
|
||||||
mDrawerListRight.setAdapter(mBookmarkAdapter);
|
|
||||||
initializeSearchSuggestions(mSearch);
|
initializeSearchSuggestions(mSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
}).run();
|
}).run();
|
||||||
|
|
||||||
View view = findViewById(R.id.bookmark_back_button);
|
|
||||||
view.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (mBookmarkManager == null)
|
|
||||||
return;
|
|
||||||
if (!mBookmarkManager.isRootFolder()) {
|
|
||||||
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mDrawerLayout.setDrawerShadow(R.drawable.drawer_right_shadow, GravityCompat.END);
|
mDrawerLayout.setDrawerShadow(R.drawable.drawer_right_shadow, GravityCompat.END);
|
||||||
mDrawerLayout.setDrawerShadow(R.drawable.drawer_left_shadow, GravityCompat.START);
|
mDrawerLayout.setDrawerShadow(R.drawable.drawer_left_shadow, GravityCompat.START);
|
||||||
|
|
||||||
@ -811,7 +768,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
return true;
|
return true;
|
||||||
case R.id.action_add_bookmark:
|
case R.id.action_add_bookmark:
|
||||||
if (mCurrentView != null && !mCurrentView.getUrl().startsWith(Constants.FILE)) {
|
if (mCurrentView != null && !mCurrentView.getUrl().startsWith(Constants.FILE)) {
|
||||||
addBookmark(mCurrentView.getTitle(), mCurrentView.getUrl());
|
BusProvider.getInstance()
|
||||||
|
.post(new BrowserEvents.AddBookmark(mCurrentView.getTitle(),
|
||||||
|
mCurrentView.getUrl()));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case R.id.action_find:
|
case R.id.action_find:
|
||||||
@ -827,75 +786,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* refreshes the underlying list of the Bookmark adapter since the bookmark
|
|
||||||
* adapter doesn't always change when notifyDataChanged gets called.
|
|
||||||
*/
|
|
||||||
private void notifyBookmarkDataSetChanged() {
|
|
||||||
if (mBookmarkAdapter != null)
|
|
||||||
mBookmarkAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addBookmark(String title, String url) {
|
|
||||||
HistoryItem bookmark = new HistoryItem(url, title);
|
|
||||||
if (mBookmarkManager.addBookmark(bookmark)) {
|
|
||||||
mBookmarkList.add(bookmark);
|
|
||||||
Collections.sort(mBookmarkList, new BookmarkManager.SortIgnoreCase());
|
|
||||||
notifyBookmarkDataSetChanged();
|
|
||||||
mSearchAdapter.refreshBookmarks();
|
|
||||||
updateBookmarkIndicator(mCurrentView.getUrl());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setBookmarkDataSet(List<HistoryItem> items, boolean animate) {
|
|
||||||
mBookmarkList.clear();
|
|
||||||
mBookmarkList.addAll(items);
|
|
||||||
notifyBookmarkDataSetChanged();
|
|
||||||
final int resource;
|
|
||||||
if (mBookmarkManager.isRootFolder())
|
|
||||||
resource = R.drawable.ic_action_star;
|
|
||||||
else
|
|
||||||
resource = R.drawable.ic_action_back;
|
|
||||||
|
|
||||||
final Animation startRotation = new Animation() {
|
|
||||||
@Override
|
|
||||||
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
|
||||||
mBookmarkTitleImage.setRotationY(90 * interpolatedTime);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
final Animation finishRotation = new Animation() {
|
|
||||||
@Override
|
|
||||||
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
|
||||||
mBookmarkTitleImage.setRotationY((-90) + (90 * interpolatedTime));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
startRotation.setAnimationListener(new AnimationListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationStart(Animation animation) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animation animation) {
|
|
||||||
mBookmarkTitleImage.setImageResource(resource);
|
|
||||||
mBookmarkTitleImage.startAnimation(finishRotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationRepeat(Animation animation) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
startRotation.setInterpolator(new AccelerateInterpolator());
|
|
||||||
finishRotation.setInterpolator(new DecelerateInterpolator());
|
|
||||||
startRotation.setDuration(250);
|
|
||||||
finishRotation.setDuration(250);
|
|
||||||
|
|
||||||
if (animate) {
|
|
||||||
mBookmarkTitleImage.startAnimation(startRotation);
|
|
||||||
} else {
|
|
||||||
mBookmarkTitleImage.setImageResource(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* method that shows a dialog asking what string the user wishes to search
|
* method that shows a dialog asking what string the user wishes to search
|
||||||
* for. It highlights the text entered.
|
* for. It highlights the text entered.
|
||||||
@ -995,146 +885,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BookmarkItemClickListener implements ListView.OnItemClickListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
if (mBookmarkList.get(position).isFolder()) {
|
|
||||||
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(mBookmarkList.get(position).getTitle(), true), true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mCurrentView != null) {
|
|
||||||
mCurrentView.loadUrl(mBookmarkList.get(position).getUrl());
|
|
||||||
}
|
|
||||||
// keep any jank from happening when the drawer is closed after the
|
|
||||||
// URL starts to load
|
|
||||||
final Handler handler = new Handler();
|
|
||||||
handler.postDelayed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mDrawerLayout.closeDrawer(mDrawerRight);
|
|
||||||
}
|
|
||||||
}, 150);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class BookmarkItemLongClickListener implements ListView.OnItemLongClickListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, final int position, long arg3) {
|
|
||||||
longPressBookmarkLink(mBookmarkList.get(position).getUrl());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes in the id of which bookmark was selected and shows a dialog that
|
|
||||||
* allows the user to rename and change the url of the bookmark
|
|
||||||
*
|
|
||||||
* @param id which id in the list was chosen
|
|
||||||
*/
|
|
||||||
private synchronized void editBookmark(final int id) {
|
|
||||||
final AlertDialog.Builder editBookmarkDialog = new AlertDialog.Builder(mActivity);
|
|
||||||
editBookmarkDialog.setTitle(R.string.title_edit_bookmark);
|
|
||||||
final EditText getTitle = new EditText(mActivity);
|
|
||||||
getTitle.setHint(R.string.hint_title);
|
|
||||||
getTitle.setText(mBookmarkList.get(id).getTitle());
|
|
||||||
getTitle.setSingleLine();
|
|
||||||
final EditText getUrl = new EditText(mActivity);
|
|
||||||
getUrl.setHint(R.string.hint_url);
|
|
||||||
getUrl.setText(mBookmarkList.get(id).getUrl());
|
|
||||||
getUrl.setSingleLine();
|
|
||||||
final AutoCompleteTextView getFolder = new AutoCompleteTextView(mActivity);
|
|
||||||
getFolder.setHint(R.string.folder);
|
|
||||||
getFolder.setText(mBookmarkList.get(id).getFolder());
|
|
||||||
getFolder.setSingleLine();
|
|
||||||
List<String> folders = mBookmarkManager.getFolderTitles();
|
|
||||||
ArrayAdapter<String> suggestionsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, folders);
|
|
||||||
getFolder.setThreshold(1);
|
|
||||||
getFolder.setAdapter(suggestionsAdapter);
|
|
||||||
LinearLayout layout = new LinearLayout(mActivity);
|
|
||||||
layout.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
int padding = Utils.dpToPx(10);
|
|
||||||
layout.setPadding(padding, padding, padding, padding);
|
|
||||||
layout.addView(getTitle);
|
|
||||||
layout.addView(getUrl);
|
|
||||||
layout.addView(getFolder);
|
|
||||||
editBookmarkDialog.setView(layout);
|
|
||||||
editBookmarkDialog.setPositiveButton(getResources().getString(R.string.action_ok),
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
HistoryItem item = new HistoryItem();
|
|
||||||
String currentFolder = mBookmarkList.get(id).getFolder();
|
|
||||||
item.setTitle(getTitle.getText().toString());
|
|
||||||
item.setUrl(getUrl.getText().toString());
|
|
||||||
item.setUrl(getUrl.getText().toString());
|
|
||||||
item.setFolder(getFolder.getText().toString());
|
|
||||||
mBookmarkManager.editBookmark(mBookmarkList.get(id), item);
|
|
||||||
|
|
||||||
List<HistoryItem> list = mBookmarkManager.getBookmarksFromFolder(currentFolder, true);
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), true);
|
|
||||||
} else {
|
|
||||||
setBookmarkDataSet(list, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCurrentView != null && mCurrentView.getUrl().startsWith(Constants.FILE)
|
|
||||||
&& mCurrentView.getUrl().endsWith(BookmarkPage.FILENAME)) {
|
|
||||||
openBookmarkPage(mWebView);
|
|
||||||
}
|
|
||||||
if (mCurrentView != null) {
|
|
||||||
updateBookmarkIndicator(mCurrentView.getUrl());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
editBookmarkDialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show a dialog to rename a folder
|
|
||||||
*
|
|
||||||
* @param id the position of the HistoryItem (folder) in the bookmark list
|
|
||||||
*/
|
|
||||||
private synchronized void renameFolder(final int id) {
|
|
||||||
final AlertDialog.Builder editFolderDialog = new AlertDialog.Builder(mActivity);
|
|
||||||
editFolderDialog.setTitle(R.string.title_rename_folder);
|
|
||||||
final EditText getTitle = new EditText(mActivity);
|
|
||||||
getTitle.setHint(R.string.hint_title);
|
|
||||||
getTitle.setText(mBookmarkList.get(id).getTitle());
|
|
||||||
getTitle.setSingleLine();
|
|
||||||
LinearLayout layout = new LinearLayout(mActivity);
|
|
||||||
layout.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
int padding = Utils.dpToPx(10);
|
|
||||||
layout.setPadding(padding, padding, padding, padding);
|
|
||||||
layout.addView(getTitle);
|
|
||||||
editFolderDialog.setView(layout);
|
|
||||||
editFolderDialog.setPositiveButton(getResources().getString(R.string.action_ok),
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
String oldTitle = mBookmarkList.get(id).getTitle();
|
|
||||||
String newTitle = getTitle.getText().toString();
|
|
||||||
|
|
||||||
mBookmarkManager.renameFolder(oldTitle, newTitle);
|
|
||||||
|
|
||||||
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
|
|
||||||
|
|
||||||
if (mCurrentView != null && mCurrentView.getUrl().startsWith(Constants.FILE)
|
|
||||||
&& mCurrentView.getUrl().endsWith(BookmarkPage.FILENAME)) {
|
|
||||||
openBookmarkPage(mWebView);
|
|
||||||
}
|
|
||||||
if (mCurrentView != null) {
|
|
||||||
updateBookmarkIndicator(mCurrentView.getUrl());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
editFolderDialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* displays the WebView contained in the LightningView Also handles the
|
* displays the WebView contained in the LightningView Also handles the
|
||||||
* removal of previous views
|
* removal of previous views
|
||||||
@ -1196,7 +946,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
}
|
}
|
||||||
}, 150);
|
}, 150);
|
||||||
|
|
||||||
updateBookmarkIndicator(mWebView.getUrl());
|
// Should update the bookmark status in BookmarksFragment
|
||||||
|
BusProvider.getInstance()
|
||||||
|
.post(new BrowserEvents.CurrentPageUrl(mCurrentView.getUrl()));
|
||||||
|
|
||||||
// new Handler().postDelayed(new Runnable() {
|
// new Handler().postDelayed(new Runnable() {
|
||||||
// @Override
|
// @Override
|
||||||
@ -1222,7 +974,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
source = intent.getExtras().getString("SOURCE");
|
source = intent.getExtras().getString("SOURCE");
|
||||||
}
|
}
|
||||||
if (num == 1) {
|
if (num == 1) {
|
||||||
mCurrentView.loadUrl(url);
|
loadUrlInCurrentView(url);
|
||||||
} else if (url != null) {
|
} else if (url != null) {
|
||||||
if (url.startsWith(Constants.FILE)) {
|
if (url.startsWith(Constants.FILE)) {
|
||||||
Utils.showSnackbar(this, R.string.message_blocked_local);
|
Utils.showSnackbar(this, R.string.message_blocked_local);
|
||||||
@ -1233,6 +985,16 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadUrlInCurrentView(final String url) {
|
||||||
|
if (mCurrentView == null) {
|
||||||
|
// This is a problem, probably an assert will be better than a return
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurrentView.loadUrl(url);
|
||||||
|
BusProvider.getInstance().post(new BrowserEvents.CurrentPageUrl(url));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void closeEmptyTab() {
|
public void closeEmptyTab() {
|
||||||
if (mWebView != null && mWebView.copyBackForwardList().getSize() == 0) {
|
if (mWebView != null && mWebView.copyBackForwardList().getSize() == 0) {
|
||||||
@ -1405,11 +1167,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
if (mDrawerLayout.isDrawerOpen(mDrawerLeft)) {
|
if (mDrawerLayout.isDrawerOpen(mDrawerLeft)) {
|
||||||
mDrawerLayout.closeDrawer(mDrawerLeft);
|
mDrawerLayout.closeDrawer(mDrawerLeft);
|
||||||
} else if (mDrawerLayout.isDrawerOpen(mDrawerRight)) {
|
} else if (mDrawerLayout.isDrawerOpen(mDrawerRight)) {
|
||||||
if (!mBookmarkManager.isRootFolder()) {
|
BusProvider.getInstance()
|
||||||
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), true);
|
.post(new BrowserEvents.UserPressedBack());
|
||||||
} else {
|
|
||||||
mDrawerLayout.closeDrawer(mDrawerRight);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (mCurrentView != null) {
|
if (mCurrentView != null) {
|
||||||
Log.d(Constants.TAG, "onBackPressed");
|
Log.d(Constants.TAG, "onBackPressed");
|
||||||
@ -1444,6 +1203,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BusProvider.getInstance().unregister(busEventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveOpenTabs() {
|
void saveOpenTabs() {
|
||||||
@ -1493,7 +1254,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
mCurrentView.onResume();
|
mCurrentView.onResume();
|
||||||
}
|
}
|
||||||
mHistoryDatabase = HistoryDatabase.getInstance(getApplicationContext());
|
mHistoryDatabase = HistoryDatabase.getInstance(getApplicationContext());
|
||||||
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
|
|
||||||
initializePreferences();
|
initializePreferences();
|
||||||
for (int n = 0; n < mWebViewList.size(); n++) {
|
for (int n = 0; n < mWebViewList.size(); n++) {
|
||||||
if (mWebViewList.get(n) != null) {
|
if (mWebViewList.get(n) != null) {
|
||||||
@ -1508,6 +1268,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(NETWORK_BROADCAST_ACTION);
|
filter.addAction(NETWORK_BROADCAST_ACTION);
|
||||||
registerReceiver(mNetworkReceiver, filter);
|
registerReceiver(mNetworkReceiver, filter);
|
||||||
|
|
||||||
|
BusProvider.getInstance().register(busEventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1522,7 +1284,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
query = query.trim();
|
query = query.trim();
|
||||||
mCurrentView.stopLoading();
|
mCurrentView.stopLoading();
|
||||||
if (mCurrentView != null) {
|
if (mCurrentView != null) {
|
||||||
mCurrentView.loadUrl(UrlUtils.smartUrlFilter(query, true, searchUrl));
|
loadUrlInCurrentView(UrlUtils.smartUrlFilter(query, true, searchUrl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1722,163 +1484,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BookmarkViewAdapter extends ArrayAdapter<HistoryItem> {
|
|
||||||
|
|
||||||
final Context context;
|
|
||||||
List<HistoryItem> data = null;
|
|
||||||
final int layoutResourceId;
|
|
||||||
final Bitmap folderIcon;
|
|
||||||
|
|
||||||
public BookmarkViewAdapter(Context context, int layoutResourceId, List<HistoryItem> data) {
|
|
||||||
super(context, layoutResourceId, data);
|
|
||||||
this.layoutResourceId = layoutResourceId;
|
|
||||||
this.context = context;
|
|
||||||
this.data = data;
|
|
||||||
this.folderIcon = mFolderBitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
View row = convertView;
|
|
||||||
BookmarkViewHolder holder;
|
|
||||||
|
|
||||||
if (row == null) {
|
|
||||||
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
|
|
||||||
row = inflater.inflate(layoutResourceId, parent, false);
|
|
||||||
|
|
||||||
holder = new BookmarkViewHolder();
|
|
||||||
holder.txtTitle = (TextView) row.findViewById(R.id.textBookmark);
|
|
||||||
holder.favicon = (ImageView) row.findViewById(R.id.faviconBookmark);
|
|
||||||
row.setTag(holder);
|
|
||||||
} else {
|
|
||||||
holder = (BookmarkViewHolder) row.getTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewCompat.jumpDrawablesToCurrentState(row);
|
|
||||||
|
|
||||||
HistoryItem web = data.get(position);
|
|
||||||
holder.txtTitle.setText(web.getTitle());
|
|
||||||
holder.favicon.setImageBitmap(mWebpageBitmap);
|
|
||||||
if (web.isFolder()) {
|
|
||||||
holder.favicon.setImageBitmap(this.folderIcon);
|
|
||||||
} else if (web.getBitmap() == null) {
|
|
||||||
getImage(holder.favicon, web);
|
|
||||||
} else {
|
|
||||||
holder.favicon.setImageBitmap(web.getBitmap());
|
|
||||||
}
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
class BookmarkViewHolder {
|
|
||||||
TextView txtTitle;
|
|
||||||
ImageView favicon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getImage(ImageView image, HistoryItem web) {
|
|
||||||
new DownloadImageTask(image, web).execute(web.getUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
|
|
||||||
|
|
||||||
final ImageView bmImage;
|
|
||||||
final HistoryItem mWeb;
|
|
||||||
|
|
||||||
public DownloadImageTask(ImageView bmImage, HistoryItem web) {
|
|
||||||
this.bmImage = bmImage;
|
|
||||||
this.mWeb = web;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Bitmap doInBackground(String... urls) {
|
|
||||||
String url = urls[0];
|
|
||||||
Bitmap mIcon = null;
|
|
||||||
// unique path for each url that is bookmarked.
|
|
||||||
String hash = String.valueOf(Utils.getDomainName(url).hashCode());
|
|
||||||
File image = new File(mActivity.getCacheDir(), hash + ".png");
|
|
||||||
String urldisplay;
|
|
||||||
try {
|
|
||||||
urldisplay = Utils.getProtocol(url) + getDomainName(url) + "/favicon.ico";
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
urldisplay = "https://www.google.com/s2/favicons?domain_url=" + url;
|
|
||||||
}
|
|
||||||
// checks to see if the image exists
|
|
||||||
if (!image.exists()) {
|
|
||||||
FileOutputStream fos = null;
|
|
||||||
InputStream in = null;
|
|
||||||
try {
|
|
||||||
// if not, download it...
|
|
||||||
URL urlDownload = new URL(urldisplay);
|
|
||||||
HttpURLConnection connection = (HttpURLConnection) urlDownload.openConnection();
|
|
||||||
connection.setDoInput(true);
|
|
||||||
connection.connect();
|
|
||||||
in = connection.getInputStream();
|
|
||||||
|
|
||||||
if (in != null) {
|
|
||||||
mIcon = BitmapFactory.decodeStream(in);
|
|
||||||
}
|
|
||||||
// ...and cache it
|
|
||||||
if (mIcon != null) {
|
|
||||||
fos = new FileOutputStream(image);
|
|
||||||
mIcon.compress(Bitmap.CompressFormat.PNG, 100, fos);
|
|
||||||
fos.flush();
|
|
||||||
Log.d(Constants.TAG, "Downloaded: " + urldisplay);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
Utils.close(in);
|
|
||||||
Utils.close(fos);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if it exists, retrieve it from the cache
|
|
||||||
mIcon = BitmapFactory.decodeFile(image.getPath());
|
|
||||||
}
|
|
||||||
if (mIcon == null) {
|
|
||||||
InputStream in = null;
|
|
||||||
FileOutputStream fos = null;
|
|
||||||
try {
|
|
||||||
// if not, download it...
|
|
||||||
URL urlDownload = new URL("https://www.google.com/s2/favicons?domain_url="
|
|
||||||
+ url);
|
|
||||||
HttpURLConnection connection = (HttpURLConnection) urlDownload.openConnection();
|
|
||||||
connection.setDoInput(true);
|
|
||||||
connection.connect();
|
|
||||||
in = connection.getInputStream();
|
|
||||||
|
|
||||||
if (in != null) {
|
|
||||||
mIcon = BitmapFactory.decodeStream(in);
|
|
||||||
}
|
|
||||||
// ...and cache it
|
|
||||||
if (mIcon != null) {
|
|
||||||
fos = new FileOutputStream(image);
|
|
||||||
mIcon.compress(Bitmap.CompressFormat.PNG, 100, fos);
|
|
||||||
fos.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
Utils.close(in);
|
|
||||||
Utils.close(fos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mIcon == null) {
|
|
||||||
return mWebpageBitmap;
|
|
||||||
} else {
|
|
||||||
return mIcon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPostExecute(Bitmap result) {
|
|
||||||
Bitmap fav = Utils.padFavicon(result);
|
|
||||||
bmImage.setImageBitmap(fav);
|
|
||||||
mWeb.setBitmap(fav);
|
|
||||||
notifyBookmarkDataSetChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getDomainName(String url) throws URISyntaxException {
|
private static String getDomainName(String url) throws URISyntaxException {
|
||||||
URI uri = new URI(url);
|
URI uri = new URI(url);
|
||||||
String domain = uri.getHost();
|
String domain = uri.getHost();
|
||||||
@ -1893,6 +1498,8 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
if (url == null || mSearch == null || mSearch.hasFocus()) {
|
if (url == null || mSearch == null || mSearch.hasFocus()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
BusProvider.getInstance()
|
||||||
|
.post(new BrowserEvents.CurrentPageUrl(url));
|
||||||
if (shortUrl && !url.startsWith(Constants.FILE)) {
|
if (shortUrl && !url.startsWith(Constants.FILE)) {
|
||||||
switch (mPreferences.getUrlBoxContentChoice()) {
|
switch (mPreferences.getUrlBoxContentChoice()) {
|
||||||
case 0: // Default, show only the domain
|
case 0: // Default, show only the domain
|
||||||
@ -2006,7 +1613,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
mCurrentView.loadUrl(HistoryPage.getHistoryPage(mActivity));
|
loadUrlInCurrentView(HistoryPage.getHistoryPage(mActivity));
|
||||||
mSearch.setText("");
|
mSearch.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2494,12 +2101,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
longPressHistoryLink(newUrl);
|
longPressHistoryLink(newUrl);
|
||||||
}
|
}
|
||||||
} else if (currentUrl.endsWith(BookmarkPage.FILENAME)) {
|
} else if (currentUrl.endsWith(BookmarkPage.FILENAME)) {
|
||||||
|
/* TODO Wtf is this?
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
longPressBookmarkLink(url);
|
longPressBookmarkLink(url);
|
||||||
} else if (result != null && result.getExtra() != null) {
|
} else if (result != null && result.getExtra() != null) {
|
||||||
final String newUrl = result.getExtra();
|
final String newUrl = result.getExtra();
|
||||||
longPressBookmarkLink(newUrl);
|
longPressBookmarkLink(newUrl);
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
@ -2523,103 +2131,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void longPressFolder(String url) {
|
|
||||||
String title;
|
|
||||||
if (url.startsWith(Constants.FILE)) {
|
|
||||||
// We are getting the title from the url
|
|
||||||
// Strip '-bookmarks.html' from the end of the url
|
|
||||||
title = url.substring(0, url.length() - BookmarkPage.FILENAME.length() - 1);
|
|
||||||
|
|
||||||
// Strip the beginning of the url off and leave only the title
|
|
||||||
title = title.substring(Constants.FILE.length() + mActivity.getFilesDir().toString().length() + 1);
|
|
||||||
} else if (url.startsWith(Constants.FOLDER)) {
|
|
||||||
title = url.substring(Constants.FOLDER.length());
|
|
||||||
} else {
|
|
||||||
title = url;
|
|
||||||
}
|
|
||||||
final int position = BookmarkManager.getIndexOfBookmark(mBookmarkList, Constants.FOLDER + title);
|
|
||||||
if (position == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
switch (which) {
|
|
||||||
case DialogInterface.BUTTON_POSITIVE:
|
|
||||||
renameFolder(position);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DialogInterface.BUTTON_NEGATIVE:
|
|
||||||
mBookmarkManager.deleteFolder(mBookmarkList.get(position).getTitle());
|
|
||||||
|
|
||||||
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
|
|
||||||
|
|
||||||
if (mCurrentView != null && mCurrentView.getUrl().startsWith(Constants.FILE)
|
|
||||||
&& mCurrentView.getUrl().endsWith(BookmarkPage.FILENAME)) {
|
|
||||||
openBookmarkPage(mWebView);
|
|
||||||
}
|
|
||||||
if (mCurrentView != null) {
|
|
||||||
updateBookmarkIndicator(mCurrentView.getUrl());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
|
|
||||||
builder.setTitle(R.string.action_folder)
|
|
||||||
.setMessage(R.string.dialog_folder)
|
|
||||||
.setCancelable(true)
|
|
||||||
.setPositiveButton(R.string.action_rename, dialogClickListener)
|
|
||||||
.setNegativeButton(R.string.action_delete, dialogClickListener)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void longPressBookmarkLink(final String url) {
|
|
||||||
if (url.startsWith(Constants.FILE) || url.startsWith(Constants.FOLDER)) {
|
|
||||||
longPressFolder(url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final int position = BookmarkManager.getIndexOfBookmark(mBookmarkList, url);
|
|
||||||
if (position == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
switch (which) {
|
|
||||||
case DialogInterface.BUTTON_POSITIVE:
|
|
||||||
newTab(mBookmarkList.get(position).getUrl(), false);
|
|
||||||
mDrawerLayout.closeDrawers();
|
|
||||||
break;
|
|
||||||
case DialogInterface.BUTTON_NEGATIVE:
|
|
||||||
if (mBookmarkManager.deleteBookmark(mBookmarkList.get(position))) {
|
|
||||||
mBookmarkList.remove(position);
|
|
||||||
notifyBookmarkDataSetChanged();
|
|
||||||
mSearchAdapter.refreshBookmarks();
|
|
||||||
openBookmarks();
|
|
||||||
if (mCurrentView != null) {
|
|
||||||
updateBookmarkIndicator(mCurrentView.getUrl());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DialogInterface.BUTTON_NEUTRAL:
|
|
||||||
editBookmark(position);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
|
|
||||||
builder.setTitle(R.string.action_bookmarks)
|
|
||||||
.setMessage(R.string.dialog_bookmark)
|
|
||||||
.setCancelable(true)
|
|
||||||
.setPositiveButton(R.string.action_new_tab, dialogClickListener)
|
|
||||||
.setNegativeButton(R.string.action_delete, dialogClickListener)
|
|
||||||
.setNeutralButton(R.string.action_edit, dialogClickListener)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void longPressHistoryLink(final String url) {
|
private void longPressHistoryLink(final String url) {
|
||||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -2637,7 +2148,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
|
|
||||||
case DialogInterface.BUTTON_NEUTRAL:
|
case DialogInterface.BUTTON_NEUTRAL:
|
||||||
if (mCurrentView != null) {
|
if (mCurrentView != null) {
|
||||||
mCurrentView.loadUrl(url);
|
loadUrlInCurrentView(url);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2664,7 +2175,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DialogInterface.BUTTON_NEGATIVE:
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
mCurrentView.loadUrl(url);
|
loadUrlInCurrentView(url);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DialogInterface.BUTTON_NEUTRAL:
|
case DialogInterface.BUTTON_NEUTRAL:
|
||||||
@ -2697,7 +2208,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DialogInterface.BUTTON_NEGATIVE:
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
mCurrentView.loadUrl(url);
|
loadUrlInCurrentView(url);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DialogInterface.BUTTON_NEUTRAL:
|
case DialogInterface.BUTTON_NEUTRAL:
|
||||||
@ -2758,17 +2269,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBookmarkIndicator(String url) {
|
|
||||||
if (url == null || !mBookmarkManager.isBookmark(url)) {
|
|
||||||
mBookmarkImage.setImageResource(R.drawable.ic_action_star);
|
|
||||||
mBookmarkImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
|
|
||||||
} else {
|
|
||||||
mBookmarkImage.setImageResource(R.drawable.ic_bookmark);
|
|
||||||
mBookmarkImage.setColorFilter(ThemeUtils.getAccentColor(this), PorterDuff.Mode.SRC_IN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
switch (v.getId()) {
|
switch (v.getId()) {
|
||||||
@ -2820,11 +2320,6 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
mCurrentView.reload();
|
mCurrentView.reload();
|
||||||
closeDrawers();
|
closeDrawers();
|
||||||
break;
|
break;
|
||||||
case R.id.action_add_bookmark:
|
|
||||||
if (mCurrentView != null && !mCurrentView.getUrl().startsWith(Constants.FILE)) {
|
|
||||||
addBookmark(mCurrentView.getTitle(), mCurrentView.getUrl());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2870,4 +2365,84 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
|||||||
PermissionsManager.getInstance().notifyPermissionsChange(permissions);
|
PermissionsManager.getInstance().notifyPermissionsChange(permissions);
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Object busEventListener = new Object() {
|
||||||
|
/**
|
||||||
|
* Load the given bookmark in the current tab, used by the the
|
||||||
|
* {@link acr.browser.lightning.fragment.BookmarksFragment}
|
||||||
|
* @param event The event as it comes from the bus
|
||||||
|
*/
|
||||||
|
@Subscribe
|
||||||
|
public void loadBookmarkInCurrentTab(final BookmarkEvents.Clicked event) {
|
||||||
|
loadUrlInCurrentView(event.bookmark.getUrl());
|
||||||
|
// keep any jank from happening when the drawer is closed after the
|
||||||
|
// URL starts to load
|
||||||
|
final Handler handler = new Handler();
|
||||||
|
handler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mDrawerLayout.closeDrawer(mDrawerRight);
|
||||||
|
}
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the given bookmark in a new tab, used by the the
|
||||||
|
* {@link acr.browser.lightning.fragment.BookmarksFragment}
|
||||||
|
* @param event The event as it comes from the bus
|
||||||
|
*/
|
||||||
|
@Subscribe
|
||||||
|
public void loadBookmarkInNewTab(final BookmarkEvents.AsNewTab event) {
|
||||||
|
newTab(event.bookmark.getUrl(), true);
|
||||||
|
mDrawerLayout.closeDrawers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When receive a {@link acr.browser.lightning.bus.BookmarkEvents.WantToBookmarkCurrentPage}
|
||||||
|
* message this receiver answer firing the
|
||||||
|
* {@link acr.browser.lightning.bus.BrowserEvents.AddBookmark} message
|
||||||
|
*
|
||||||
|
* @param event basically a marker
|
||||||
|
*/
|
||||||
|
@Subscribe
|
||||||
|
public void bookmarkCurrentPage(final BookmarkEvents.WantToBookmarkCurrentPage event) {
|
||||||
|
BusProvider.getInstance()
|
||||||
|
.post(new BrowserEvents
|
||||||
|
.AddBookmark(mCurrentView.getTitle(), mCurrentView.getUrl()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This message is received when a bookmark was added by the
|
||||||
|
* {@link acr.browser.lightning.fragment.BookmarksFragment}
|
||||||
|
*
|
||||||
|
* @param event a marker
|
||||||
|
*/
|
||||||
|
@Subscribe
|
||||||
|
public void bookmarkAdded(final BookmarkEvents.Added event) {
|
||||||
|
mSearchAdapter.refreshBookmarks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the browser that a bookmark was deleted
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
@Subscribe
|
||||||
|
public void bookmarkDeleted(final BookmarkEvents.Deleted event) {
|
||||||
|
BusProvider.getInstance()
|
||||||
|
.post(new BrowserEvents.CurrentPageUrl(mCurrentView.getUrl()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link acr.browser.lightning.fragment.BookmarksFragment} send this message on reply
|
||||||
|
* to {@link acr.browser.lightning.bus.BrowserEvents.UserPressedBack} message if the
|
||||||
|
* fragement is showing the boomarks root folder.
|
||||||
|
*
|
||||||
|
* @param event a marker
|
||||||
|
*/
|
||||||
|
@Subscribe
|
||||||
|
public void closeBookmarks(final BookmarkEvents.CloseBookmarks event) {
|
||||||
|
mDrawerLayout.closeDrawer(mDrawerRight);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,10 @@ import android.view.Menu;
|
|||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
import android.webkit.CookieSyncManager;
|
import android.webkit.CookieSyncManager;
|
||||||
|
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import acr.browser.lightning.R;
|
import acr.browser.lightning.R;
|
||||||
|
import acr.browser.lightning.bus.BookmarkEvents;
|
||||||
import acr.browser.lightning.preference.PreferenceManager;
|
import acr.browser.lightning.preference.PreferenceManager;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@ -60,4 +63,6 @@ public class MainActivity extends BrowserActivity {
|
|||||||
closeDrawers();
|
closeDrawers();
|
||||||
moveTaskToBack(true);
|
moveTaskToBack(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
package acr.browser.lightning.bus;
|
||||||
|
|
||||||
|
import acr.browser.lightning.database.HistoryItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stefano Pacifici on 26/08/15.
|
||||||
|
*/
|
||||||
|
public final class BookmarkEvents {
|
||||||
|
|
||||||
|
private BookmarkEvents() {
|
||||||
|
// No instances
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bookmark was clicked
|
||||||
|
*/
|
||||||
|
public final static class Clicked {
|
||||||
|
public final HistoryItem bookmark;
|
||||||
|
|
||||||
|
public Clicked(final HistoryItem bookmark) {
|
||||||
|
this.bookmark = bookmark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user ask to open the bookmark as new tab
|
||||||
|
*/
|
||||||
|
public final static class AsNewTab {
|
||||||
|
public final HistoryItem bookmark;
|
||||||
|
|
||||||
|
public AsNewTab(final HistoryItem bookmark) {
|
||||||
|
this.bookmark = bookmark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user ask to delete the selected bookmark
|
||||||
|
*/
|
||||||
|
public static class Deleted {
|
||||||
|
public final HistoryItem item;
|
||||||
|
|
||||||
|
public Deleted(final HistoryItem item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user ask to bookmark the currently displayed page
|
||||||
|
*/
|
||||||
|
public static class WantToBookmarkCurrentPage {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bookmark was added
|
||||||
|
*/
|
||||||
|
public static class Added {
|
||||||
|
public final HistoryItem item;
|
||||||
|
|
||||||
|
public Added(final HistoryItem item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link acr.browser.lightning.fragment.BookmarksFragment} want to know the url (and title)
|
||||||
|
* of the currently shown web page.
|
||||||
|
*/
|
||||||
|
public static class WantInfoAboutCurrentPage {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sended by the {@link acr.browser.lightning.fragment.BookmarksFragment} when it wants to close
|
||||||
|
* itself (generally in reply to a {@link acr.browser.lightning.bus.BrowserEvents.UserPressedBack}
|
||||||
|
* event.
|
||||||
|
*/
|
||||||
|
public static class CloseBookmarks {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package acr.browser.lightning.bus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stefano Pacifici on 26/08/15.
|
||||||
|
*/
|
||||||
|
public final class BrowserEvents {
|
||||||
|
|
||||||
|
private BrowserEvents() {
|
||||||
|
// No instances
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to reply to the {@link acr.browser.lightning.fragment.BookmarksFragment} message
|
||||||
|
* {@link acr.browser.lightning.bus.BookmarkEvents.WantToBookmarkCurrentPage}. The interaction
|
||||||
|
* result is a new bookmark added.
|
||||||
|
*/
|
||||||
|
public static class AddBookmark {
|
||||||
|
public final String title, url;
|
||||||
|
|
||||||
|
public AddBookmark(final String title, final String url) {
|
||||||
|
this.title = title;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to reply to {@link acr.browser.lightning.fragment.BookmarksFragment} message
|
||||||
|
* {@link acr.browser.lightning.bus.BookmarkEvents.WantInfoAboutCurrentPage}. This is generally
|
||||||
|
* used to update the {@link acr.browser.lightning.fragment.BookmarksFragment} interface.
|
||||||
|
*/
|
||||||
|
public static class CurrentPageUrl {
|
||||||
|
public final String url;
|
||||||
|
|
||||||
|
public CurrentPageUrl(final String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the BookmarksFragment and TabsFragment that the user pressed the back button
|
||||||
|
*/
|
||||||
|
public static class UserPressedBack {
|
||||||
|
}
|
||||||
|
}
|
19
app/src/main/java/acr/browser/lightning/bus/BusProvider.java
Normal file
19
app/src/main/java/acr/browser/lightning/bus/BusProvider.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package acr.browser.lightning.bus;
|
||||||
|
|
||||||
|
import com.squareup.otto.Bus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stefano Pacifici on 25/08/15.
|
||||||
|
*/
|
||||||
|
public class BusProvider {
|
||||||
|
|
||||||
|
private static final Bus bus = new Bus();
|
||||||
|
|
||||||
|
public static Bus getInstance() {
|
||||||
|
return bus;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BusProvider() {
|
||||||
|
// No instances
|
||||||
|
}
|
||||||
|
}
|
@ -56,6 +56,6 @@ public interface BrowserController {
|
|||||||
|
|
||||||
boolean proxyIsNotReady();
|
boolean proxyIsNotReady();
|
||||||
|
|
||||||
void updateBookmarkIndicator(String url);
|
// void updateBookmarkIndicator(String url);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.database.Cursor;
|
|||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.provider.Browser;
|
import android.provider.Browser;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@ -13,9 +14,12 @@ import org.json.JSONObject;
|
|||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@ -32,6 +36,8 @@ import acr.browser.lightning.utils.Utils;
|
|||||||
|
|
||||||
public class BookmarkManager {
|
public class BookmarkManager {
|
||||||
|
|
||||||
|
private static final String TAG = BookmarkManager.class.getSimpleName();
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private static final String TITLE = "title";
|
private static final String TITLE = "title";
|
||||||
private static final String URL = "url";
|
private static final String URL = "url";
|
||||||
@ -251,24 +257,36 @@ public class BookmarkManager {
|
|||||||
* @return returns a list of bookmarks that can be sorted
|
* @return returns a list of bookmarks that can be sorted
|
||||||
*/
|
*/
|
||||||
public synchronized List<HistoryItem> getAllBookmarks(boolean sort) {
|
public synchronized List<HistoryItem> getAllBookmarks(boolean sort) {
|
||||||
List<HistoryItem> bookmarks = new ArrayList<>();
|
final List<HistoryItem> bookmarks = new ArrayList<>();
|
||||||
File bookmarksFile = new File(mContext.getFilesDir(), FILE_BOOKMARKS);
|
final File bookmarksFile = new File(mContext.getFilesDir(), FILE_BOOKMARKS);
|
||||||
|
|
||||||
BufferedReader bookmarksReader = null;
|
BufferedReader bookmarksReader = null;
|
||||||
try {
|
try {
|
||||||
bookmarksReader = new BufferedReader(new FileReader(bookmarksFile));
|
final InputStream inputStream;
|
||||||
|
if (bookmarksFile.exists() && bookmarksFile.isFile()) {
|
||||||
|
inputStream = new FileInputStream(bookmarksFile);
|
||||||
|
} else {
|
||||||
|
inputStream = mContext.getResources().openRawResource(R.raw.default_bookmarks);
|
||||||
|
}
|
||||||
|
bookmarksReader =
|
||||||
|
new BufferedReader(new InputStreamReader(inputStream));
|
||||||
String line;
|
String line;
|
||||||
while ((line = bookmarksReader.readLine()) != null) {
|
while ((line = bookmarksReader.readLine()) != null) {
|
||||||
JSONObject object = new JSONObject(line);
|
try {
|
||||||
HistoryItem item = new HistoryItem();
|
JSONObject object = new JSONObject(line);
|
||||||
item.setTitle(object.getString(TITLE));
|
HistoryItem item = new HistoryItem();
|
||||||
item.setUrl(object.getString(URL));
|
item.setTitle(object.getString(TITLE));
|
||||||
item.setFolder(object.getString(FOLDER));
|
item.setUrl(object.getString(URL));
|
||||||
item.setOrder(object.getInt(ORDER));
|
item.setFolder(object.getString(FOLDER));
|
||||||
item.setImageId(R.drawable.ic_bookmark);
|
item.setOrder(object.getInt(ORDER));
|
||||||
bookmarks.add(item);
|
item.setImageId(R.drawable.ic_bookmark);
|
||||||
}
|
bookmarks.add(item);
|
||||||
} catch (IOException | JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
Log.e(TAG, "Can't parse line " + line, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Error reading the bookmarks file", e);
|
||||||
} finally {
|
} finally {
|
||||||
Utils.close(bookmarksReader);
|
Utils.close(bookmarksReader);
|
||||||
}
|
}
|
||||||
@ -498,17 +516,4 @@ public class BookmarkManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] DEV = {"https://twitter.com/RestainoAnthony", "The Developer"};
|
|
||||||
private static final String[] FACEBOOK = {"https://www.facebook.com/", "Facebook"};
|
|
||||||
private static final String[] TWITTER = {"https://twitter.com", "Twitter"};
|
|
||||||
private static final String[] GOOGLE = {"https://www.google.com/", "Google"};
|
|
||||||
private static final String[] YAHOO = {"https://www.yahoo.com/", "Yahoo"};
|
|
||||||
public static final String[][] DEFAULT_BOOKMARKS = {
|
|
||||||
DEV,
|
|
||||||
FACEBOOK,
|
|
||||||
TWITTER,
|
|
||||||
GOOGLE,
|
|
||||||
YAHOO
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,493 @@
|
|||||||
|
package acr.browser.lightning.fragment;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.IdRes;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.view.ViewCompat;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.AccelerateInterpolator;
|
||||||
|
import android.view.animation.Animation;
|
||||||
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
import android.view.animation.Transformation;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
|
import android.widget.AdapterView.OnItemLongClickListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.AutoCompleteTextView;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.squareup.otto.Bus;
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import acr.browser.lightning.R;
|
||||||
|
import acr.browser.lightning.activity.BrowserActivity;
|
||||||
|
import acr.browser.lightning.bus.BookmarkEvents;
|
||||||
|
import acr.browser.lightning.bus.BrowserEvents;
|
||||||
|
import acr.browser.lightning.bus.BusProvider;
|
||||||
|
import acr.browser.lightning.database.BookmarkManager;
|
||||||
|
import acr.browser.lightning.database.HistoryItem;
|
||||||
|
import acr.browser.lightning.preference.PreferenceManager;
|
||||||
|
import acr.browser.lightning.utils.DownloadImageTask;
|
||||||
|
import acr.browser.lightning.utils.ThemeUtils;
|
||||||
|
import acr.browser.lightning.utils.Utils;
|
||||||
|
|
||||||
|
import static android.support.v7.app.AlertDialog.Builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stefano Pacifici on 25/08/15. Based on Anthony C. Restaino's code.
|
||||||
|
*/
|
||||||
|
public class BookmarksFragment extends Fragment implements View.OnClickListener, View.OnLongClickListener {
|
||||||
|
|
||||||
|
// Managers
|
||||||
|
private BookmarkManager mBookmarkManager;
|
||||||
|
|
||||||
|
// Adapter
|
||||||
|
private BookmarkViewAdapter mBookmarkAdapter;
|
||||||
|
|
||||||
|
// Preloaded images
|
||||||
|
private Bitmap mWebpageBitmap, mFolderBitmap;
|
||||||
|
|
||||||
|
// Bookmarks
|
||||||
|
private List<HistoryItem> mBookmarks = new ArrayList<>();
|
||||||
|
|
||||||
|
// Views
|
||||||
|
private ListView mBookmarksListView;
|
||||||
|
private ImageView mBookmarkTitleImage, mBookmarkImage;
|
||||||
|
|
||||||
|
// Colors
|
||||||
|
private int mIconColor;
|
||||||
|
|
||||||
|
// Init asynchronously the bookmark manager
|
||||||
|
private final Runnable initBookmarkManager = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final Context context = getContext();
|
||||||
|
mBookmarkManager = BookmarkManager.getInstance(context.getApplicationContext());
|
||||||
|
mBookmarkAdapter = new BookmarkViewAdapter(context, mBookmarks);
|
||||||
|
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
|
||||||
|
mBookmarksListView.setAdapter(mBookmarkAdapter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle bookmark click
|
||||||
|
private final OnItemClickListener itemClickListener = new OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
final HistoryItem item = mBookmarks.get(position);
|
||||||
|
if (item.isFolder()) {
|
||||||
|
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(item.getTitle(), true),
|
||||||
|
true);
|
||||||
|
} else {
|
||||||
|
BusProvider.getInstance().post(new BookmarkEvents.Clicked(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final OnItemLongClickListener itemLongClickListener = new OnItemLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
final HistoryItem item = mBookmarks.get(position);
|
||||||
|
handleLongPress(item, position);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
final View view = inflater.inflate(R.layout.bookmark_drawer, container, false);
|
||||||
|
mBookmarksListView = (ListView) view.findViewById(R.id.right_drawer_list);
|
||||||
|
mBookmarksListView.setOnItemClickListener(itemClickListener);
|
||||||
|
mBookmarksListView.setOnItemLongClickListener(itemLongClickListener);
|
||||||
|
mBookmarkTitleImage = (ImageView) view.findViewById(R.id.starIcon);
|
||||||
|
mBookmarkImage = (ImageView) view.findViewById(R.id.icon_star);
|
||||||
|
final View backView = view.findViewById(R.id.bookmark_back_button);
|
||||||
|
backView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (mBookmarkManager == null)
|
||||||
|
return;
|
||||||
|
if (!mBookmarkManager.isRootFolder()) {
|
||||||
|
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Must be called here, only here we have a reference to the ListView
|
||||||
|
new Thread(initBookmarkManager).run();
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
|
// TODO this code depend way too much on BrowserActivity
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
final BrowserActivity activity = (BrowserActivity) getActivity();
|
||||||
|
final PreferenceManager preferenceManager =PreferenceManager.getInstance();
|
||||||
|
boolean darkTheme = preferenceManager.getUseTheme() != 0 || activity.isIncognito();
|
||||||
|
mWebpageBitmap = ThemeUtils.getThemedBitmap(activity, R.drawable.ic_webpage, darkTheme);
|
||||||
|
mFolderBitmap = ThemeUtils.getThemedBitmap(activity, R.drawable.ic_folder, darkTheme);
|
||||||
|
mIconColor = darkTheme ? ThemeUtils.getIconDarkThemeColor(activity) :
|
||||||
|
ThemeUtils.getIconLightThemeColor(activity);
|
||||||
|
setupFrameLayoutButton(getView(), R.id.action_add_bookmark, R.id.icon_star);
|
||||||
|
mBookmarkTitleImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
BusProvider.getInstance().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
BusProvider.getInstance().unregister(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void addBookmark(final BrowserEvents.AddBookmark event) {
|
||||||
|
final HistoryItem item = new HistoryItem(event.url, event.title);
|
||||||
|
if (mBookmarkManager.addBookmark(item)) {
|
||||||
|
mBookmarks.add(item);
|
||||||
|
Collections.sort(mBookmarks, new BookmarkManager.SortIgnoreCase());
|
||||||
|
mBookmarkAdapter.notifyDataSetChanged();
|
||||||
|
BusProvider.getInstance()
|
||||||
|
.post(new BookmarkEvents.Added(item));
|
||||||
|
updateBookmarkIndicator(event.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void currentPageInfo(final BrowserEvents.CurrentPageUrl event) {
|
||||||
|
updateBookmarkIndicator(event.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBookmarkIndicator(final String url) {
|
||||||
|
if (!mBookmarkManager.isBookmark(url)) {
|
||||||
|
mBookmarkImage.setImageResource(R.drawable.ic_action_star);
|
||||||
|
mBookmarkImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
|
||||||
|
} else {
|
||||||
|
mBookmarkImage.setImageResource(R.drawable.ic_bookmark);
|
||||||
|
mBookmarkImage.setColorFilter(ThemeUtils.getAccentColor(getContext()), PorterDuff.Mode.SRC_IN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void userPressedBack(final BrowserEvents.UserPressedBack event) {
|
||||||
|
if (mBookmarkManager.isRootFolder()) {
|
||||||
|
BusProvider.getInstance()
|
||||||
|
.post(new BookmarkEvents.CloseBookmarks());
|
||||||
|
} else {
|
||||||
|
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBookmarkDataSet(List<HistoryItem> items, boolean animate) {
|
||||||
|
mBookmarks.clear();
|
||||||
|
mBookmarks.addAll(items);
|
||||||
|
mBookmarkAdapter.notifyDataSetChanged();
|
||||||
|
final int resource;
|
||||||
|
if (mBookmarkManager.isRootFolder())
|
||||||
|
resource = R.drawable.ic_action_star;
|
||||||
|
else
|
||||||
|
resource = R.drawable.ic_action_back;
|
||||||
|
|
||||||
|
final Animation startRotation = new Animation() {
|
||||||
|
@Override
|
||||||
|
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
||||||
|
mBookmarkTitleImage.setRotationY(90 * interpolatedTime);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
final Animation finishRotation = new Animation() {
|
||||||
|
@Override
|
||||||
|
protected void applyTransformation(float interpolatedTime, Transformation t) {
|
||||||
|
mBookmarkTitleImage.setRotationY((-90) + (90 * interpolatedTime));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
startRotation.setAnimationListener(new Animation.AnimationListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationStart(Animation animation) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animation animation) {
|
||||||
|
mBookmarkTitleImage.setImageResource(resource);
|
||||||
|
mBookmarkTitleImage.startAnimation(finishRotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAnimationRepeat(Animation animation) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
startRotation.setInterpolator(new AccelerateInterpolator());
|
||||||
|
finishRotation.setInterpolator(new DecelerateInterpolator());
|
||||||
|
startRotation.setDuration(250);
|
||||||
|
finishRotation.setDuration(250);
|
||||||
|
|
||||||
|
if (animate) {
|
||||||
|
mBookmarkTitleImage.startAnimation(startRotation);
|
||||||
|
} else {
|
||||||
|
mBookmarkTitleImage.setImageResource(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this is basically a copy/paste from BrowserActivity, should be changed
|
||||||
|
private void setupFrameLayoutButton(@NonNull View view, @IdRes int buttonId, @IdRes int imageId) {
|
||||||
|
FrameLayout frameButton = (FrameLayout) view.findViewById(buttonId);
|
||||||
|
frameButton.setOnClickListener(this);
|
||||||
|
frameButton.setOnLongClickListener(this);
|
||||||
|
ImageView buttonImage = (ImageView) view.findViewById(imageId);
|
||||||
|
buttonImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleLongPress(final HistoryItem item, final int position) {
|
||||||
|
if (item.isFolder()) {
|
||||||
|
longPressFolder(item, position);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
final Bus bus = BusProvider.getInstance();
|
||||||
|
final DialogInterface.OnClickListener dialogClickListener =
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
switch (which) {
|
||||||
|
case DialogInterface.BUTTON_POSITIVE:
|
||||||
|
bus.post(new BookmarkEvents.AsNewTab(item));
|
||||||
|
break;
|
||||||
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
|
if (mBookmarkManager.deleteBookmark(item)) {
|
||||||
|
mBookmarks.remove(position);
|
||||||
|
mBookmarkAdapter.notifyDataSetChanged();
|
||||||
|
bus.post(new BookmarkEvents.Deleted(item));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DialogInterface.BUTTON_NEUTRAL:
|
||||||
|
editBookmark(item, position);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
|
builder.setTitle(R.string.action_bookmarks)
|
||||||
|
.setMessage(R.string.dialog_bookmark)
|
||||||
|
.setCancelable(true)
|
||||||
|
.setPositiveButton(R.string.action_new_tab, dialogClickListener)
|
||||||
|
.setNegativeButton(R.string.action_delete, dialogClickListener)
|
||||||
|
.setNeutralButton(R.string.action_edit, dialogClickListener)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void longPressFolder(final HistoryItem item, final int position) {
|
||||||
|
final DialogInterface.OnClickListener dialogClickListener =
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
switch (which) {
|
||||||
|
case DialogInterface.BUTTON_POSITIVE:
|
||||||
|
renameFolder(item, position);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DialogInterface.BUTTON_NEGATIVE:
|
||||||
|
mBookmarkManager.deleteFolder(item.getTitle());
|
||||||
|
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
|
||||||
|
BusProvider.getInstance().post(new BookmarkEvents.Deleted(item));
|
||||||
|
/* TODO Restore Bookmarkpage
|
||||||
|
if (mCurrentView != null && mCurrentView.getUrl().startsWith(Constants.FILE)
|
||||||
|
&& mCurrentView.getUrl().endsWith(BookmarkPage.FILENAME)) {
|
||||||
|
openBookmarkPage(mWebView);
|
||||||
|
}*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Builder builder = new Builder(getContext());
|
||||||
|
builder.setTitle(R.string.action_folder)
|
||||||
|
.setMessage(R.string.dialog_folder)
|
||||||
|
.setCancelable(true)
|
||||||
|
.setPositiveButton(R.string.action_rename, dialogClickListener)
|
||||||
|
.setNegativeButton(R.string.action_delete, dialogClickListener)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes in the id of which bookmark was selected and shows a dialog that
|
||||||
|
* allows the user to rename and change the url of the bookmark
|
||||||
|
*
|
||||||
|
* @param item the bookmark
|
||||||
|
* @param position the position inside the adapter
|
||||||
|
*/
|
||||||
|
private synchronized void editBookmark(final HistoryItem item, final int position) {
|
||||||
|
final Builder editBookmarkDialog = new Builder(getContext());
|
||||||
|
editBookmarkDialog.setTitle(R.string.title_edit_bookmark);
|
||||||
|
final View dialogLayout = View.inflate(getContext(), R.layout.dialog_edit_bookmark, null);
|
||||||
|
final EditText getTitle = (EditText) dialogLayout.findViewById(R.id.bookmark_title);
|
||||||
|
getTitle.setText(item.getTitle());
|
||||||
|
final EditText getUrl = (EditText) dialogLayout.findViewById(R.id.bookmark_url);
|
||||||
|
getUrl.setText(item.getUrl());
|
||||||
|
final AutoCompleteTextView getFolder =
|
||||||
|
(AutoCompleteTextView) dialogLayout.findViewById(R.id.bookmark_folder);
|
||||||
|
getFolder.setHint(R.string.folder);
|
||||||
|
getFolder.setText(item.getFolder());
|
||||||
|
final List<String> folders = mBookmarkManager.getFolderTitles();
|
||||||
|
final ArrayAdapter<String> suggestionsAdapter = new ArrayAdapter<>(getContext(),
|
||||||
|
android.R.layout.simple_dropdown_item_1line, folders);
|
||||||
|
getFolder.setThreshold(1);
|
||||||
|
getFolder.setAdapter(suggestionsAdapter);
|
||||||
|
editBookmarkDialog.setView(dialogLayout);
|
||||||
|
editBookmarkDialog.setPositiveButton(getResources().getString(R.string.action_ok),
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
HistoryItem editedItem = new HistoryItem();
|
||||||
|
String currentFolder = item.getFolder();
|
||||||
|
editedItem.setTitle(getTitle.getText().toString());
|
||||||
|
editedItem.setUrl(getUrl.getText().toString());
|
||||||
|
editedItem.setUrl(getUrl.getText().toString());
|
||||||
|
editedItem.setFolder(getFolder.getText().toString());
|
||||||
|
mBookmarkManager.editBookmark(item, editedItem);
|
||||||
|
|
||||||
|
List<HistoryItem> list = mBookmarkManager.getBookmarksFromFolder(currentFolder, true);
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), true);
|
||||||
|
} else {
|
||||||
|
setBookmarkDataSet(list, false);
|
||||||
|
}
|
||||||
|
BusProvider.getInstance()
|
||||||
|
.post(new BookmarkEvents.WantInfoAboutCurrentPage());
|
||||||
|
/* TODO Restore BookmarkPage
|
||||||
|
if (mCurrentView != null && mCurrentView.getUrl().startsWith(Constants.FILE)
|
||||||
|
&& mCurrentView.getUrl().endsWith(BookmarkPage.FILENAME)) {
|
||||||
|
openBookmarkPage(mWebView);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editBookmarkDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a dialog to rename a folder
|
||||||
|
*
|
||||||
|
* @param id the position of the HistoryItem (folder) in the bookmark list
|
||||||
|
*/
|
||||||
|
private synchronized void renameFolder(final HistoryItem item, final int id) {
|
||||||
|
final Context context = getContext();
|
||||||
|
final Builder editFolderDialog = new Builder(context);
|
||||||
|
editFolderDialog.setTitle(R.string.title_rename_folder);
|
||||||
|
final EditText getTitle = new EditText(context);
|
||||||
|
getTitle.setHint(R.string.hint_title);
|
||||||
|
getTitle.setText(item.getTitle());
|
||||||
|
getTitle.setSingleLine();
|
||||||
|
LinearLayout layout = new LinearLayout(context);
|
||||||
|
layout.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
int padding = Utils.dpToPx(10);
|
||||||
|
layout.setPadding(padding, padding, padding, padding);
|
||||||
|
layout.addView(getTitle);
|
||||||
|
editFolderDialog.setView(layout);
|
||||||
|
editFolderDialog.setPositiveButton(getResources().getString(R.string.action_ok),
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
String oldTitle = item.getTitle();
|
||||||
|
String newTitle = getTitle.getText().toString();
|
||||||
|
|
||||||
|
mBookmarkManager.renameFolder(oldTitle, newTitle);
|
||||||
|
|
||||||
|
setBookmarkDataSet(mBookmarkManager.getBookmarksFromFolder(null, true), false);
|
||||||
|
/* TODO Restore Bookmarkpage
|
||||||
|
if (mCurrentView != null && mCurrentView.getUrl().startsWith(Constants.FILE)
|
||||||
|
&& mCurrentView.getUrl().endsWith(BookmarkPage.FILENAME)) {
|
||||||
|
openBookmarkPage(mWebView);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editFolderDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
switch (v.getId()) {
|
||||||
|
case R.id.action_add_bookmark:
|
||||||
|
BusProvider.getInstance().post(new BookmarkEvents.WantToBookmarkCurrentPage());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View v) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BookmarkViewAdapter extends ArrayAdapter<HistoryItem> {
|
||||||
|
|
||||||
|
final Context context;
|
||||||
|
|
||||||
|
public BookmarkViewAdapter(Context context, List<HistoryItem> data) {
|
||||||
|
super(context, R.layout.bookmark_list_item, data);
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
View row = convertView;
|
||||||
|
BookmarkViewHolder holder;
|
||||||
|
|
||||||
|
if (row == null) {
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(context);
|
||||||
|
row = inflater.inflate(R.layout.bookmark_list_item, parent, false);
|
||||||
|
|
||||||
|
holder = new BookmarkViewHolder();
|
||||||
|
holder.txtTitle = (TextView) row.findViewById(R.id.textBookmark);
|
||||||
|
holder.favicon = (ImageView) row.findViewById(R.id.faviconBookmark);
|
||||||
|
row.setTag(holder);
|
||||||
|
} else {
|
||||||
|
holder = (BookmarkViewHolder) row.getTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewCompat.jumpDrawablesToCurrentState(row);
|
||||||
|
|
||||||
|
HistoryItem web = mBookmarks.get(position);
|
||||||
|
holder.txtTitle.setText(web.getTitle());
|
||||||
|
holder.favicon.setImageBitmap(mWebpageBitmap);
|
||||||
|
if (web.isFolder()) {
|
||||||
|
holder.favicon.setImageBitmap(mFolderBitmap);
|
||||||
|
} else if (web.getBitmap() == null) {
|
||||||
|
new DownloadImageTask(holder.favicon, web, mWebpageBitmap).execute();
|
||||||
|
} else {
|
||||||
|
holder.favicon.setImageBitmap(web.getBitmap());
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
class BookmarkViewHolder {
|
||||||
|
TextView txtTitle;
|
||||||
|
ImageView favicon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -44,7 +44,6 @@ public class PreferenceManager {
|
|||||||
public static final String INVERT_COLORS = "invertColors";
|
public static final String INVERT_COLORS = "invertColors";
|
||||||
public static final String READING_TEXT_SIZE = "readingTextSize";
|
public static final String READING_TEXT_SIZE = "readingTextSize";
|
||||||
public static final String THEME = "Theme";
|
public static final String THEME = "Theme";
|
||||||
public static final String DEFAULT_BOOKMARKS = "defaultBookmarks";
|
|
||||||
public static final String TEXT_ENCODING = "textEncoding";
|
public static final String TEXT_ENCODING = "textEncoding";
|
||||||
public static final String CLEAR_WEBSTORAGE_EXIT = "clearWebStorageExit";
|
public static final String CLEAR_WEBSTORAGE_EXIT = "clearWebStorageExit";
|
||||||
public static final String SHOW_TABS_IN_DRAWER = "showTabsInDrawer";
|
public static final String SHOW_TABS_IN_DRAWER = "showTabsInDrawer";
|
||||||
@ -117,10 +116,6 @@ public class PreferenceManager {
|
|||||||
return mPrefs.getBoolean(Name.COOKIES, true);
|
return mPrefs.getBoolean(Name.COOKIES, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getDefaultBookmarks() {
|
|
||||||
return mPrefs.getBoolean(Name.DEFAULT_BOOKMARKS, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDownloadDirectory() {
|
public String getDownloadDirectory() {
|
||||||
return mPrefs.getString(Name.DOWNLOAD_DIRECTORY, Environment.DIRECTORY_DOWNLOADS);
|
return mPrefs.getString(Name.DOWNLOAD_DIRECTORY, Environment.DIRECTORY_DOWNLOADS);
|
||||||
}
|
}
|
||||||
@ -317,10 +312,6 @@ public class PreferenceManager {
|
|||||||
putBoolean(Name.COOKIES, enable);
|
putBoolean(Name.COOKIES, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultBookmarks(boolean show) {
|
|
||||||
putBoolean(Name.DEFAULT_BOOKMARKS, show);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDownloadDirectory(String directory) {
|
public void setDownloadDirectory(String directory) {
|
||||||
putString(Name.DOWNLOAD_DIRECTORY, directory);
|
putString(Name.DOWNLOAD_DIRECTORY, directory);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,127 @@
|
|||||||
|
package acr.browser.lightning.utils;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import acr.browser.lightning.constant.Constants;
|
||||||
|
import acr.browser.lightning.database.HistoryItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Stefano Pacifici on 25/08/15.
|
||||||
|
*/
|
||||||
|
public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
|
||||||
|
|
||||||
|
final ImageView bmImage;
|
||||||
|
final HistoryItem mWeb;
|
||||||
|
final File mCacheDir;
|
||||||
|
final String mUrl;
|
||||||
|
final Bitmap mDefaultBitmap;
|
||||||
|
|
||||||
|
public DownloadImageTask(@NonNull ImageView bmImage, @NonNull HistoryItem web,
|
||||||
|
@NonNull Bitmap defaultBitmap) {
|
||||||
|
assert bmImage != null;
|
||||||
|
assert web != null;
|
||||||
|
assert defaultBitmap != null;
|
||||||
|
this.bmImage = bmImage;
|
||||||
|
this.mWeb = web;
|
||||||
|
this.mCacheDir = bmImage.getContext().getCacheDir();
|
||||||
|
this.mUrl = web.getUrl();
|
||||||
|
this.mDefaultBitmap = defaultBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Bitmap doInBackground(Void... params) {
|
||||||
|
Bitmap mIcon = null;
|
||||||
|
// unique path for each url that is bookmarked.
|
||||||
|
final Uri uri = Uri.parse(mUrl);
|
||||||
|
|
||||||
|
final String hash = "" + Utils.hash(uri.getHost());
|
||||||
|
final File image = new File(mCacheDir, hash + ".png");
|
||||||
|
final Uri urldisplay = Uri.fromParts(uri.getScheme(), uri.getHost(), "favicon.ico");
|
||||||
|
// checks to see if the image exists
|
||||||
|
if (!image.exists()) {
|
||||||
|
FileOutputStream fos = null;
|
||||||
|
InputStream in = null;
|
||||||
|
try {
|
||||||
|
// if not, download it...
|
||||||
|
final URL urlDownload = new URL(urldisplay.toString());
|
||||||
|
final HttpURLConnection connection = (HttpURLConnection) urlDownload.openConnection();
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.connect();
|
||||||
|
in = connection.getInputStream();
|
||||||
|
|
||||||
|
if (in != null) {
|
||||||
|
mIcon = BitmapFactory.decodeStream(in);
|
||||||
|
}
|
||||||
|
// ...and cache it
|
||||||
|
if (mIcon != null) {
|
||||||
|
fos = new FileOutputStream(image);
|
||||||
|
mIcon.compress(Bitmap.CompressFormat.PNG, 100, fos);
|
||||||
|
fos.flush();
|
||||||
|
Log.d(Constants.TAG, "Downloaded: " + urldisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
Utils.close(in);
|
||||||
|
Utils.close(fos);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// if it exists, retrieve it from the cache
|
||||||
|
mIcon = BitmapFactory.decodeFile(image.getPath());
|
||||||
|
}
|
||||||
|
if (mIcon == null) {
|
||||||
|
InputStream in = null;
|
||||||
|
FileOutputStream fos = null;
|
||||||
|
try {
|
||||||
|
// if not, download it...
|
||||||
|
final URL urlDownload = new URL("https://www.google.com/s2/favicons?domain_url="
|
||||||
|
+ uri.toString());
|
||||||
|
final HttpURLConnection connection = (HttpURLConnection) urlDownload.openConnection();
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.connect();
|
||||||
|
in = connection.getInputStream();
|
||||||
|
|
||||||
|
if (in != null) {
|
||||||
|
mIcon = BitmapFactory.decodeStream(in);
|
||||||
|
}
|
||||||
|
// ...and cache it
|
||||||
|
if (mIcon != null) {
|
||||||
|
fos = new FileOutputStream(image);
|
||||||
|
mIcon.compress(Bitmap.CompressFormat.PNG, 100, fos);
|
||||||
|
fos.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
Utils.close(in);
|
||||||
|
Utils.close(fos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mIcon == null) {
|
||||||
|
return mDefaultBitmap;
|
||||||
|
} else {
|
||||||
|
return mIcon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPostExecute(Bitmap result) {
|
||||||
|
final Bitmap fav = Utils.padFavicon(result);
|
||||||
|
bmImage.setImageBitmap(fav);
|
||||||
|
mWeb.setBitmap(fav);
|
||||||
|
// notifyBookmarkDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
@ -34,8 +34,11 @@ import android.webkit.URLUtil;
|
|||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -309,4 +312,20 @@ public final class Utils {
|
|||||||
canvas.drawPath(wallpath, paint);
|
canvas.drawPath(wallpath, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the SHA-1 hash of the given string
|
||||||
|
* @param str the string to hash
|
||||||
|
* @return the long representation of the hash
|
||||||
|
*/
|
||||||
|
public static long hash(final String str) {
|
||||||
|
try {
|
||||||
|
final MessageDigest digest = MessageDigest.getInstance("SHA-1");
|
||||||
|
final byte[] bytes = digest.digest(str.getBytes());
|
||||||
|
final BigInteger intRepr = new BigInteger(bytes);
|
||||||
|
return intRepr.longValue();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
Log.e(Constants.TAG, "The device has not SHA-1 support", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,8 @@ import java.io.IOException;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
import acr.browser.lightning.R;
|
import acr.browser.lightning.R;
|
||||||
|
import acr.browser.lightning.bus.BrowserEvents;
|
||||||
|
import acr.browser.lightning.bus.BusProvider;
|
||||||
import acr.browser.lightning.constant.Constants;
|
import acr.browser.lightning.constant.Constants;
|
||||||
import acr.browser.lightning.constant.StartPage;
|
import acr.browser.lightning.constant.StartPage;
|
||||||
import acr.browser.lightning.controller.BrowserController;
|
import acr.browser.lightning.controller.BrowserController;
|
||||||
@ -98,6 +100,7 @@ public class LightningView {
|
|||||||
private PermissionsManager mPermissionsManager;
|
private PermissionsManager mPermissionsManager;
|
||||||
private static final String[] PERMISSIONS = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
|
private static final String[] PERMISSIONS = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public LightningView(Activity activity, String url, boolean darkTheme, boolean isIncognito) {
|
public LightningView(Activity activity, String url, boolean darkTheme, boolean isIncognito) {
|
||||||
|
|
||||||
mActivity = activity;
|
mActivity = activity;
|
||||||
@ -175,6 +178,7 @@ public class LightningView {
|
|||||||
* if you don't have a reference to them
|
* if you don't have a reference to them
|
||||||
* @param context the context in which the WebView was created
|
* @param context the context in which the WebView was created
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public synchronized void initializePreferences(@Nullable WebSettings settings, Context context) {
|
public synchronized void initializePreferences(@Nullable WebSettings settings, Context context) {
|
||||||
if (settings == null && mWebView == null) {
|
if (settings == null && mWebView == null) {
|
||||||
return;
|
return;
|
||||||
@ -293,6 +297,7 @@ public class LightningView {
|
|||||||
* @param settings the WebSettings object to use.
|
* @param settings the WebSettings object to use.
|
||||||
* @param context the Context which was used to construct the WebView.
|
* @param context the Context which was used to construct the WebView.
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("NewApi")
|
||||||
private void initializeSettings(WebSettings settings, Context context) {
|
private void initializeSettings(WebSettings settings, Context context) {
|
||||||
if (API < Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
if (API < Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||||
settings.setAppCacheMaxSize(Long.MAX_VALUE);
|
settings.setAppCacheMaxSize(Long.MAX_VALUE);
|
||||||
@ -347,6 +352,7 @@ public class LightningView {
|
|||||||
mToggleDesktop = !mToggleDesktop;
|
mToggleDesktop = !mToggleDesktop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public void setUserAgent(Context context, int choice) {
|
public void setUserAgent(Context context, int choice) {
|
||||||
if (mWebView == null) return;
|
if (mWebView == null) return;
|
||||||
WebSettings settings = mWebView.getSettings();
|
WebSettings settings = mWebView.getSettings();
|
||||||
@ -526,6 +532,7 @@ public class LightningView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
public synchronized void find(String text) {
|
public synchronized void find(String text) {
|
||||||
if (mWebView != null) {
|
if (mWebView != null) {
|
||||||
if (API >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
if (API >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
@ -645,11 +652,11 @@ public class LightningView {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
@Override
|
@Override
|
||||||
public void onPageFinished(WebView view, String url) {
|
public void onPageFinished(WebView view, String url) {
|
||||||
if (view.isShown()) {
|
if (view.isShown()) {
|
||||||
mBrowserController.updateUrl(url, true);
|
mBrowserController.updateUrl(url, true);
|
||||||
mBrowserController.updateBookmarkIndicator(url);
|
|
||||||
view.postInvalidate();
|
view.postInvalidate();
|
||||||
}
|
}
|
||||||
if (view.getTitle() == null || view.getTitle().isEmpty()) {
|
if (view.getTitle() == null || view.getTitle().isEmpty()) {
|
||||||
@ -667,7 +674,6 @@ public class LightningView {
|
|||||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||||
if (isShown()) {
|
if (isShown()) {
|
||||||
mBrowserController.updateUrl(url, false);
|
mBrowserController.updateUrl(url, false);
|
||||||
mBrowserController.updateBookmarkIndicator(url);
|
|
||||||
mBrowserController.showActionBar();
|
mBrowserController.showActionBar();
|
||||||
}
|
}
|
||||||
mTitle.setFavicon(mWebpageBitmap);
|
mTitle.setFavicon(mWebpageBitmap);
|
||||||
@ -723,6 +729,7 @@ public class LightningView {
|
|||||||
private boolean mIsRunning = false;
|
private boolean mIsRunning = false;
|
||||||
private float mZoomScale = 0.0f;
|
private float mZoomScale = 0.0f;
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
@Override
|
@Override
|
||||||
public void onScaleChanged(final WebView view, final float oldScale, final float newScale) {
|
public void onScaleChanged(final WebView view, final float oldScale, final float newScale) {
|
||||||
if (view.isShown() && mTextReflow && API >= android.os.Build.VERSION_CODES.KITKAT) {
|
if (view.isShown() && mTextReflow && API >= android.os.Build.VERSION_CODES.KITKAT) {
|
||||||
|
@ -27,7 +27,19 @@
|
|||||||
|
|
||||||
<include layout="@layout/tab_drawer" />
|
<include layout="@layout/tab_drawer" />
|
||||||
|
|
||||||
<include layout="@layout/bookmark_drawer" />
|
<FrameLayout
|
||||||
|
android:weightSum="1"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
android:id="@+id/right_drawer"
|
||||||
|
android:layout_width="@dimen/navigation_width"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<fragment
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
class="acr.browser.lightning.fragment.BookmarksFragment" />
|
||||||
|
</FrameLayout>
|
||||||
|
<!-- include layout="@layout/bookmark_drawer" / -->
|
||||||
</android.support.v4.widget.DrawerLayout>
|
</android.support.v4.widget.DrawerLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,13 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/right_drawer"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="@dimen/navigation_width"
|
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="end"
|
|
||||||
android:background="?attr/drawerBackground"
|
android:background="?attr/drawerBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:weightSum="1"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
29
app/src/main/res/layout/dialog_edit_bookmark.xml
Normal file
29
app/src/main/res/layout/dialog_edit_bookmark.xml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/bookmark_title"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:hint="@string/hint_title"/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/bookmark_url"
|
||||||
|
android:hint="@string/hint_url"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:inputType="textUri"/>
|
||||||
|
|
||||||
|
<AutoCompleteTextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/bookmark_folder"
|
||||||
|
android:hint="@string/folder"
|
||||||
|
android:singleLine="true"/>
|
||||||
|
</LinearLayout>
|
5
app/src/main/res/raw/default_bookmarks.dat
Normal file
5
app/src/main/res/raw/default_bookmarks.dat
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{"url": "https://twitter.com/RestainoAnthony", "title": "The Developer", "folder": "", "order": 0}
|
||||||
|
{"url": "https://www.facebook.com/", "title": "Facebook", "folder": "", "order": 2}
|
||||||
|
{"url": "https://twitter.com", "title": "Twitter", "folder": "", "order": 3}
|
||||||
|
{"url": "https://www.google.com/", "title": "Google", "folder": "", "order": 4}
|
||||||
|
{"url": "https://www.yahoo.com/", "title": "Yahoo", "folder": "", "order": 5}
|
2
external/netcipher
vendored
2
external/netcipher
vendored
@ -1 +1 @@
|
|||||||
Subproject commit be233148c1c644b77b4f90089c82d85a50940c57
|
Subproject commit 442d282b07940a9992f54fcf61c44e12472cca83
|
Loading…
x
Reference in New Issue
Block a user