Added SlidingPane for mobile and tablets.

captchafix
Florens Douwes 12 years ago
parent a2983afc1c
commit fe9c38b86a
  1. 4
      Chan/AndroidManifest.xml
  2. BIN
      Chan/res/drawable-hdpi/panel_shadow.9.png
  3. BIN
      Chan/res/drawable-mdpi/panel_shadow.9.png
  4. BIN
      Chan/res/drawable-xhdpi/panel_shadow.9.png
  5. BIN
      Chan/res/drawable-xxhdpi/panel_shadow.9.png
  6. 26
      Chan/res/layout/activity_base.xml
  7. 13
      Chan/res/layout/board_select_spinner.xml
  8. 33
      Chan/res/menu/base.xml
  9. 3
      Chan/res/values/dimens.xml
  10. 10
      Chan/res/values/strings.xml
  11. 3
      Chan/res/values/styles.xml
  12. 8
      Chan/res/xml/preference.xml
  13. 6
      Chan/src/org/floens/chan/ChanApplication.java
  14. 117
      Chan/src/org/floens/chan/activity/BaseActivity.java
  15. 295
      Chan/src/org/floens/chan/activity/BoardActivity.java
  16. 11
      Chan/src/org/floens/chan/activity/CatalogActivity.java
  17. 48
      Chan/src/org/floens/chan/activity/ReplyActivity.java
  18. 142
      Chan/src/org/floens/chan/activity/ThreadActivity.java
  19. 109
      Chan/src/org/floens/chan/fragment/ReplyFragment.java
  20. 4
      Chan/src/org/floens/chan/fragment/SettingsFragment.java
  21. 21
      Chan/src/org/floens/chan/fragment/ThreadFragment.java
  22. 3
      Chan/src/org/floens/chan/manager/BoardManager.java
  23. 4
      Chan/src/org/floens/chan/manager/PinnedManager.java
  24. 134
      Chan/src/org/floens/chan/manager/ThreadManager.java
  25. 4
      Chan/src/org/floens/chan/view/PostView.java

@ -51,6 +51,10 @@
android:name="org.floens.chan.activity.CatalogActivity"
android:configChanges="keyboardHidden|orientation|screenSize" >
</activity>
<activity
android:name="org.floens.chan.activity.ReplyActivity"
android:configChanges="keyboardHidden|orientation|screenSize" >
</activity>
<activity
android:name="org.floens.chan.activity.SettingsActivity"
android:label="@string/action_settings"

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

@ -3,11 +3,27 @@
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<android.support.v4.widget.SlidingPaneLayout
android:id="@+id/pane_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/left_pane"
android:layout_width="300dp"
android:layout_height="match_parent"
android:background="#FFFFFFFF" />
<FrameLayout
android:id="@+id/right_pane"
android:layout_width="340dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#FFE5E5E5" />
</android.support.v4.widget.SlidingPaneLayout>
<ListView
android:id="@+id/left_drawer"
android:layout_width="280dp"

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#FFF3F3F3"
android:gravity="center_vertical"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>

@ -1,15 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_reload"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="2"
android:showAsAction="always"
android:title="@string/action_reload" />
android:id="@+id/action_reload"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="1"
android:showAsAction="always"
android:title="@string/action_reload" />
<item
android:id="@+id/action_pin"
android:icon="@drawable/ic_action_make_available_offline"
android:orderInCategory="2"
android:showAsAction="always"
android:title="@string/action_pin" />
<item
android:id="@+id/action_reply"
android:icon="@drawable/ic_action_chat"
android:orderInCategory="4"
android:showAsAction="ifRoom"
android:title="@string/action_reply" />
<item
android:id="@+id/action_share"
android:orderInCategory="5"
android:showAsAction="never"
android:title="@string/action_share"
android:actionProviderClass="android.widget.ShareActionProvider" />
<item
android:id="@+id/action_open_browser"
android:orderInCategory="5"
android:orderInCategory="6"
android:showAsAction="never"
android:title="@string/action_open_browser" />

@ -1,7 +1,8 @@
<resources>
<dimen name="general_padding">12dp</dimen>
<dimen name="post_padding">11dp</dimen>
<dimen name="post_padding">10dp</dimen>
<dimen name="post_comment_padding">11dp</dimen>
<dimen name="post_text_padding">6dp</dimen>
<dimen name="thumbnail_size">70dp</dimen>
<dimen name="post_icon_width">24dp</dimen>

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cancel">Cancel</string>
<string name="change">Change</string>
<string name="app_name">Chan</string>
<string name="action_settings">Settings</string>
<string name="action_reload">Reload</string>
@ -8,6 +11,7 @@
<string name="action_reply">Reply</string>
<string name="action_open_browser">Open in browser</string>
<string name="action_catalog">Open catalog</string>
<string name="action_share">Share</string>
<string name="preference_general">General</string>
@ -46,8 +50,10 @@
<string name="drawer_close">Close drawer</string>
<string name="drawer_pinned">Pinned threads</string>
<string name="drawer_pinned_change_title">Enter title</string>
<string name="reply">Reply</string>
<string name="reply">Reply to</string>
<string name="reply_to_board">Make thread in</string>
<string name="reply_name">Name</string>
<string name="reply_email">Email</string>
<string name="reply_subject">Subject</string>
@ -67,6 +73,8 @@
<string name="open_link_confirmation_preference">Ask before opening links</string>
<string name="open_link_confirmation">Open link?</string>
<string name="default_name_preference">Default name</string>
<string name="default_email_preference">Default email</string>
<string name="open_unknown_title">Unsupported link</string>
<string name="open_unknown">Chan can\'t open this link. Opening it in your browser instead.</string>

@ -2,7 +2,6 @@
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
</style>
<style name="Theme.ImageList" parent="AppTheme">
@ -11,8 +10,6 @@
<item name="android:backgroundDimEnabled">true</item>
</style>
</resources>

@ -16,6 +16,14 @@
android:key="preference_open_link_confirmation"
android:defaultValue="true" />
<EditTextPreference
android:title="@string/default_name_preference"
android:key="preference_default_name" />
<EditTextPreference
android:title="@string/default_email_preference"
android:key="preference_default_email" />
</PreferenceCategory>
<PreferenceCategory

@ -6,7 +6,9 @@ import org.floens.chan.manager.ReplyManager;
import org.floens.chan.utils.IconCache;
import android.app.Application;
import android.content.SharedPreferences;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import com.android.volley.RequestQueue;
import com.android.volley.extra.BitmapLruImageCache;
@ -46,6 +48,10 @@ public class ChanApplication extends Application {
return pinnedManager;
}
public static SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(instance);
}
@Override
public void onCreate() {
super.onCreate();

@ -5,53 +5,62 @@ import org.floens.chan.R;
import org.floens.chan.adapter.PinnedAdapter;
import org.floens.chan.animation.SwipeDismissListViewTouchListener;
import org.floens.chan.animation.SwipeDismissListViewTouchListener.DismissCallbacks;
import org.floens.chan.entity.Loadable;
import org.floens.chan.entity.Pin;
import org.floens.chan.entity.Post;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnShowListener;
import android.content.Intent;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.support.v4.widget.DrawerLayout.SimpleDrawerListener;
import android.support.v4.widget.SlidingPaneLayout;
import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ShareActionProvider;
/**
* Activities that use ThreadFragment need to extend BaseActivity.
* BaseActivity provides callbacks for when the user clicks a post,
* or clicks an item in the drawer.
*/
public abstract class BaseActivity extends Activity {
public abstract class BaseActivity extends Activity implements PanelSlideListener {
private final static int ACTION_OPEN_URL = 1;
protected Loadable loadable;
protected DrawerLayout drawer;
protected ListView drawerList;
protected DrawerListener drawerListener;
protected ActionBarDrawerToggle drawerListener;
protected SlidingPaneLayout pane;
protected ShareActionProvider shareActionProvider;
/**
* Called when a post has been clicked in the pinned drawer
* @param post
*/
abstract public void onDrawerClicked(Pin post);
/**
* Called when a post has been clicked in the listview
* @param post
*/
abstract public void onPostClicked(Post post);
abstract public void onOPClicked(Post post);
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -59,20 +68,20 @@ public abstract class BaseActivity extends Activity {
setContentView(R.layout.activity_base);
drawer = (DrawerLayout)findViewById(R.id.drawer_layout);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
setupDrawer(drawer);
final ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowTitleEnabled(true);
loadable = new Loadable();
pane = (SlidingPaneLayout) findViewById(R.id.pane_container);
pane.setPanelSlideListener(this);
pane.setParallaxDistance(200);
pane.setShadowResource(R.drawable.panel_shadow);
pane.setSliderFadeColor(0xcce5e5e5);
pane.openPane();
}
protected void setupDrawer(DrawerLayout drawer) {
if (drawerListener == null) {
drawerListener = new SimpleDrawerListener() {};
return;
}
drawer.setDrawerListener(drawerListener);
@ -92,6 +101,18 @@ public abstract class BaseActivity extends Activity {
}
});
drawerList.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Pin post = adapter.getItem(position);
if (post == null || post.type == Pin.Type.HEADER) return false;
changePinTitle(post);
return true;
}
});
SwipeDismissListViewTouchListener touchListener = new SwipeDismissListViewTouchListener(drawerList,
new DismissCallbacks() {
@Override
@ -128,11 +149,23 @@ public abstract class BaseActivity extends Activity {
return true;
}
@Override
public void onPanelClosed(View view) {
}
@Override
public void onPanelOpened(View view) {
}
@Override
public void onPanelSlide(View view, float offset) {
}
/**
* Set the url that Android Beam will send to other users.
* Set the url that Android Beam and the share action will send.
* @param url
*/
public void setNfcPushUrl(String url) {
public void setShareUrl(String url) {
NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
if (adapter != null) {
@ -147,6 +180,13 @@ public abstract class BaseActivity extends Activity {
NdefMessage message = new NdefMessage(new NdefRecord[] {record});
adapter.setNdefPushMessage(message, this);
}
if (shareActionProvider != null) {
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.putExtra(android.content.Intent.EXTRA_TEXT, url);
share.setType("text/plain");
shareActionProvider.setShareIntent(share);
}
}
/**
@ -175,6 +215,45 @@ public abstract class BaseActivity extends Activity {
startActivity(data);
}
}
private void changePinTitle(final Pin pin) {
final EditText text = new EditText(this);
text.setSingleLine();
text.setText(pin.loadable.title);
text.setSelectAllOnFocus(true);
AlertDialog dialog = new AlertDialog.Builder(this)
.setPositiveButton(R.string.change, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface d, int which) {
String value = text.getText().toString();
if (!TextUtils.isEmpty(value)) {
pin.loadable.title = value;
}
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface d, int which) {
}
})
.setTitle(R.string.drawer_pinned_change_title)
.setView(text)
.create();
text.requestFocus();
dialog.setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(text, 0);
}
});
dialog.show();
}
}

@ -6,7 +6,6 @@ import java.util.List;
import org.floens.chan.ChanApplication;
import org.floens.chan.R;
import org.floens.chan.entity.Loadable;
import org.floens.chan.entity.Loadable.Mode;
import org.floens.chan.entity.Pin;
import org.floens.chan.entity.Post;
import org.floens.chan.fragment.ReplyFragment;
@ -23,11 +22,17 @@ import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ShareActionProvider;
public class BoardActivity extends BaseActivity implements ActionBar.OnNavigationListener {
private Loadable boardLoadable = new Loadable();
private Loadable threadLoadable = new Loadable();
private ThreadFragment boardFragment;
private ThreadFragment threadFragment;
private boolean boardSetByIntent = false;
@ -35,38 +40,41 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadable.mode = Loadable.Mode.BOARD;
boardLoadable.mode = Loadable.Mode.BOARD;
threadLoadable.mode = Loadable.Mode.THREAD;
boardFragment = ThreadFragment.newInstance(this);
threadFragment = ThreadFragment.newInstance(this);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, threadFragment);
ft.replace(R.id.left_pane, boardFragment);
ft.replace(R.id.right_pane, threadFragment);
ft.commitAllowingStateLoss();
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setHomeButtonEnabled(true);
updateActionBarState();
final ActionBar actionBar = getActionBar();
actionBar.setListNavigationCallbacks(
new ArrayAdapter<String>(
actionBar.getThemedContext(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
ChanApplication.getBoardManager().getMyBoardsKeys()
), this);
new ArrayAdapter<String>(
actionBar.getThemedContext(),
R.layout.board_select_spinner,
android.R.id.text1,
ChanApplication.getBoardManager().getMyBoardsKeys()
), this);
Intent startIntent = getIntent();
Uri startUri = startIntent.getData();
if (savedInstanceState != null) {
loadable.readFromBundle(this, savedInstanceState);
loadable.no = 0;
loadable.listViewIndex = 0;
loadable.listViewTop = 0;
setNavigationFromBoardValue(loadable.board);
boardLoadable.readFromBundle(this, savedInstanceState);
boardLoadable.no = 0;
boardLoadable.listViewIndex = 0;
boardLoadable.listViewTop = 0;
setNavigationFromBoardValue(boardLoadable.board);
} else if (startUri != null) {
handleStartURI(startUri);
handleIntentURI(startUri);
} else {
actionBar.setSelectedNavigationItem(0);
getActionBar().setSelectedNavigationItem(0);
}
}
@ -74,7 +82,7 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
loadable.writeToBundle(this, outState);
boardLoadable.writeToBundle(this, outState);
}
@Override
@ -87,8 +95,8 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
@Override
public boolean onNavigationItemSelected(int position, long id) {
if (!boardSetByIntent) {
loadable = new Loadable(ChanApplication.getBoardManager().getMyBoardsValues().get(position));
startLoading(loadable);
boardLoadable = new Loadable(ChanApplication.getBoardManager().getMyBoardsValues().get(position));
startLoadingBoard(boardLoadable);
}
boardSetByIntent = false;
@ -97,98 +105,207 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (((ActionBarDrawerToggle) drawerListener).onOptionsItemSelected(item)) {
return true;
}
switch(item.getItemId()) {
case R.id.action_catalog:
Loadable l = new Loadable();
l.mode = Mode.CATALOG;
l.board = loadable.board;
startCatalogActivity(l);
return true;
case R.id.action_reload:
threadFragment.reload();
return true;
case R.id.action_reply:
ReplyFragment reply = ReplyFragment.newInstance(threadFragment);
reply.show(getFragmentManager(), "replyDialog");
return true;
case R.id.action_open_browser:
openUrl(ChanUrls.getBoardUrlDesktop(loadable.board));
return true;
}
return super.onOptionsItemSelected(item);
}
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
shareActionProvider = (ShareActionProvider) menu.findItem(R.id.action_share).getActionProvider();
return true;
}
@Override
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
((ActionBarDrawerToggle) drawerListener).onConfigurationChanged(newConfig);
drawerListener.onConfigurationChanged(newConfig);
}
@Override
public void onDrawerClicked(Pin pin) {
startThreadActivity(pin.loadable);
startLoadingThread(pin.loadable);
drawer.closeDrawer(drawerList);
}
@Override
public void onPostClicked(Post post) {
startThreadActivity(new Loadable(post.board, post.no, post.subject));
public void onOPClicked(Post post) {
startLoadingThread(new Loadable(post.board, post.no, post.subject));
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
((ActionBarDrawerToggle) drawerListener).syncState();
drawerListener.syncState();
}
private void startLoading(Loadable loadable) {
threadFragment.startLoading(loadable);
setNfcPushUrl(ChanUrls.getBoardUrlDesktop(loadable.board));
@Override
public void onBackPressed() {
if (pane.isOpen()) {
super.onBackPressed();
} else {
pane.openPane();
}
}
private void startThreadActivity(Loadable loadable) {
Intent intent = new Intent(this, ThreadActivity.class);
Bundle bundle = new Bundle();
loadable.writeToBundle(this, bundle);
private void updateActionBarState() {
final ActionBar actionBar = getActionBar();
if (pane.isSlideable()) {
if (pane.isOpen()) {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setHomeButtonEnabled(true);
actionBar.setTitle("");
drawerListener.setDrawerIndicatorEnabled(true);
} else {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(threadLoadable.title);
drawerListener.setDrawerIndicatorEnabled(false);
}
actionBar.setDisplayHomeAsUpEnabled(true);
} else {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
drawerListener.setDrawerIndicatorEnabled(true);
actionBar.setTitle(threadLoadable.title);
actionBar.setDisplayHomeAsUpEnabled(false);
}
actionBar.setDisplayShowTitleEnabled(true);
intent.putExtras(bundle);
invalidateOptionsMenu();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean open = pane.isOpen();
setMenuItemEnabled(menu.findItem(R.id.action_pin), !open);
return super.onPrepareOptionsMenu(menu);
}
private void setMenuItemEnabled(MenuItem item, boolean enabled) {
if (item != null) {
item.setVisible(enabled);
item.setEnabled(enabled);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerListener.onOptionsItemSelected(item)) {
return true;
}
switch(item.getItemId()) {
case R.id.action_reload:
if (pane.isOpen()) {
boardFragment.reload();
} else {
if (threadFragment.getThreadManager().hasThread()) {
threadFragment.reload();
}
}
return true;
case R.id.action_reply:
if (pane.isOpen()) {
startReply(pane.isSlideable(), boardFragment);
} else {
if (threadFragment.getThreadManager().hasThread()) {
startReply(pane.isSlideable(), threadFragment);
}
}
return true;
case R.id.action_pin:
if (threadFragment.getThreadManager().hasThread()) {
Pin pin = new Pin();
pin.loadable = threadLoadable;
ChanApplication.getPinnedManager().add(pin);
drawer.openDrawer(drawerList);
}
return true;
case R.id.action_open_browser:
if (pane.isOpen()) {
openUrl(ChanUrls.getBoardUrlDesktop(boardLoadable.board));
} else {
if (threadFragment.getThreadManager().hasThread()) {
openUrl(ChanUrls.getThreadUrlDesktop(threadLoadable.board, threadLoadable.no));
}
}
return true;
case android.R.id.home:
pane.openPane();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onPanelClosed(View view) {
updateActionBarState();
}
@Override
public void onPanelOpened(View view) {
updateActionBarState();
}
private void startReply(boolean inActivity, ThreadFragment fragment) {
if (inActivity) {
ReplyActivity.setThreadFragment(fragment);
Intent i = new Intent(this, ReplyActivity.class);
startActivity(i);
} else {
ReplyFragment reply = ReplyFragment.newInstance(fragment);
reply.show(getFragmentManager(), "replyDialog");
}
}
private void startLoadingBoard(Loadable loadable) {
this.boardLoadable = loadable;
boardFragment.startLoading(loadable);
setShareUrl(ChanUrls.getBoardUrlDesktop(loadable.board));
startActivity(intent);
updateActionBarState();
}
private void startCatalogActivity(Loadable loadable) {
Intent intent = new Intent(this, CatalogActivity.class);
private void startLoadingThread(Loadable loadable) {
Pin pin = ChanApplication.getPinnedManager().findPinByLoadable(loadable);
if (pin != null) {
// Use the loadable from the pin.
// This way we can store the listview position in the pin loadable,
// and not in a separate loadable instance.
loadable = pin.loadable;
}
threadLoadable = loadable;
Bundle bundle = new Bundle();
loadable.writeToBundle(this, bundle);
threadFragment.startLoading(loadable);
setShareUrl(ChanUrls.getThreadUrlDesktop(loadable.board, loadable.no));
if (TextUtils.isEmpty(loadable.title)) {
loadable.title = "/" + loadable.board + "/" + loadable.no;
}
intent.putExtras(bundle);
pane.closePane();
startActivity(intent);
updateActionBarState();
}
/**
* Handle opening from an external url.
* @param startUri
*/
private void handleStartURI(Uri startUri) {
private void handleIntentURI(Uri startUri) {
List<String> parts = startUri.getPathSegments();
if (parts.size() == 1) {
@ -196,9 +313,9 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
String rawBoard = parts.get(0);
if (ChanApplication.getBoardManager().getBoardExists(rawBoard)) {
loadable.board = rawBoard;
boardLoadable.board = rawBoard;
boardSetByIntent = true;
startLoading(loadable);
startLoadingBoard(boardLoadable);
ActionBar actionBar = getActionBar();
if (!setNavigationFromBoardValue(rawBoard)) {
@ -209,7 +326,7 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
}
} else {
fallbackOpenUrl(startUri.toString());
handleIntentURIFallback(startUri.toString());
}
} else if (parts.size() == 3) {
// Thread mode
@ -222,14 +339,14 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
} catch (NumberFormatException e) {}
if (no >= 0 && ChanApplication.getBoardManager().getBoardExists(rawBoard)) {
loadable.board = rawBoard;
boardLoadable.board = rawBoard;
boardSetByIntent = true;
startLoading(loadable);
startLoadingBoard(boardLoadable);
startThreadActivity(new Loadable(rawBoard, no));
startLoadingThread(new Loadable(rawBoard, no));
finish();
} else {
fallbackOpenUrl(startUri.toString());
handleIntentURIFallback(startUri.toString());
return;
}
} else {
@ -237,7 +354,7 @@ public class BoardActivity extends BaseActivity implements ActionBar.OnNavigatio
}
}
private void fallbackOpenUrl(final String url) {
private void handleIntentURIFallback(final String url) {
new AlertDialog.Builder(this)
.setTitle(R.string.open_unknown_title)
.setMessage(R.string.open_unknown)

@ -8,17 +8,18 @@ import org.floens.chan.entity.Post;
import org.floens.chan.fragment.ThreadFragment;
import org.floens.chan.net.ChanUrls;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
public class CatalogActivity extends BaseActivity {
private final Loadable loadable = new Loadable();
private ThreadFragment threadFragment;
@Override
public void onPostClicked(Post post) {
public void onOPClicked(Post post) {
}
@ -34,9 +35,9 @@ public class CatalogActivity extends BaseActivity {
loadable.mode = Mode.CATALOG;
threadFragment = ThreadFragment.newInstance(this);
FragmentTransaction ft = getFragmentManager().beginTransaction();
/*FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, threadFragment);
ft.commitAllowingStateLoss();
ft.commitAllowingStateLoss();*/
Bundle bundle = getIntent().getExtras();
@ -89,7 +90,7 @@ public class CatalogActivity extends BaseActivity {
private void startLoading(Loadable loadable) {
threadFragment.startLoading(loadable);
setNfcPushUrl(ChanUrls.getCatalogUrlDesktop(loadable.board));
setShareUrl(ChanUrls.getCatalogUrlDesktop(loadable.board));
if (TextUtils.isEmpty(loadable.title)) {
loadable.title = "Catalog /" + loadable.board + "/";

@ -0,0 +1,48 @@
package org.floens.chan.activity;
import org.floens.chan.fragment.ReplyFragment;
import org.floens.chan.fragment.ThreadFragment;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
public class ReplyActivity extends Activity {
private static ThreadFragment threadFragment;
public static void setThreadFragment(ThreadFragment tf) {
threadFragment = tf;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (threadFragment != null) {
getActionBar().setDisplayHomeAsUpEnabled(true);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(android.R.id.content, ReplyFragment.newInstance(threadFragment));
ft.commitAllowingStateLoss();
threadFragment = null;
} else {
Log.e("Chan", "ThreadFragment was null, exiting!");
finish();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}

@ -1,30 +1,23 @@
package org.floens.chan.activity;
import java.util.ArrayList;
import org.floens.chan.ChanApplication;
import org.floens.chan.R;
import org.floens.chan.entity.Loadable;
import org.floens.chan.entity.Pin;
import org.floens.chan.entity.Post;
import org.floens.chan.entity.PostLinkable;
import org.floens.chan.fragment.PostPopupFragment;
import org.floens.chan.fragment.ReplyFragment;
import org.floens.chan.fragment.ThreadFragment;
import org.floens.chan.net.ChanUrls;
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
public class ThreadActivity extends BaseActivity {
private Loadable loadable = new Loadable();
private ThreadFragment threadFragment;
@Override
@ -35,7 +28,7 @@ public class ThreadActivity extends BaseActivity {
threadFragment = ThreadFragment.newInstance(this);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, threadFragment);
ft.replace(R.id.right_pane, threadFragment);
ft.commitAllowingStateLoss();
Bundle bundle = getIntent().getExtras();
@ -51,14 +44,6 @@ public class ThreadActivity extends BaseActivity {
finish();
}
Pin pin = ChanApplication.getPinnedManager().findPinByLoadable(loadable);
if (pin != null) {
// Use the loadable from the pin.
// This way we can store the listview position in the pin loadable,
// and not in a separate loadable instance.
loadable = pin.loadable;
}
startLoading(loadable);
}
@ -71,7 +56,7 @@ public class ThreadActivity extends BaseActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.thread, menu);
// getMenuInflater().inflate(R.menu.thread, menu);
return super.onCreateOptionsMenu(menu);
}
@ -118,43 +103,18 @@ public class ThreadActivity extends BaseActivity {
startLoading(loadable);
}
/**
* When the user clicks a post:
* a. when there's one linkable, open the linkable.
* b. when there's more than one linkable, show the user multiple options to select from.
* @param post The post that was clicked.
*/
@Override
public void onPostClicked(Post post) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final ArrayList<PostLinkable> linkables = post.linkables;
if (linkables.size() > 0) {
if (linkables.size() == 1) {
handleLinkableSelected(linkables.get(0));
} else {
String[] keys = new String[linkables.size()];
for (int i = 0; i < linkables.size(); i++) {
keys[i] = linkables.get(i).key;
}
builder.setItems(keys, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handleLinkableSelected(linkables.get(which));
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
}
private void startLoading(Loadable loadable) {
Pin pin = ChanApplication.getPinnedManager().findPinByLoadable(loadable);
if (pin != null) {
// Use the loadable from the pin.
// This way we can store the listview position in the pin loadable,
// and not in a separate loadable instance.
loadable = pin.loadable;
}
threadFragment.startLoading(loadable);
setNfcPushUrl(ChanUrls.getThreadUrlDesktop(loadable.board, loadable.no));
setShareUrl(ChanUrls.getThreadUrlDesktop(loadable.board, loadable.no));
if (TextUtils.isEmpty(loadable.title)) {
loadable.title = "/" + loadable.board + "/" + loadable.no;
@ -162,75 +122,9 @@ public class ThreadActivity extends BaseActivity {
getActionBar().setTitle(loadable.title);
}
/**
* Handle when a linkable has been clicked.
* @param linkable the selected linkable.
*/
private void handleLinkableSelected(final PostLinkable linkable) {
if (linkable.type == PostLinkable.Type.QUOTE) {
showPostPopup(linkable);
} else if (linkable.type == PostLinkable.Type.LINK) {
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("preference_open_link_confirmation", true)) {
AlertDialog dialog = new AlertDialog.Builder(this)
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
openLink(linkable);
}
})
.setTitle(R.string.open_link_confirmation)
.setMessage(linkable.value)
.create();
dialog.show();
} else {
openLink(linkable);
}
}
}
/**
* When a linkable to a post has been clicked,
* show a dialog with the referenced post in it.
* @param linkable the clicked linkable.
*/
private void showPostPopup(PostLinkable linkable) {
String value = linkable.value;
Post post = null;
try {
// Get post id
String[] splitted = value.split("#p");
if (splitted.length == 2) {
int id = Integer.parseInt(splitted[1]);
post = threadFragment.getThreadManager().getPostById(id);
if (post != null) {
PostPopupFragment popup = PostPopupFragment.newInstance(post, threadFragment.getThreadManager());
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(popup, "postPopup");
ft.commitAllowingStateLoss();
}
}
} catch(NumberFormatException e) {
e.printStackTrace();
}
}
/**
* Open an url.
* @param linkable Linkable with an url.
*/
private void openLink(PostLinkable linkable) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(linkable.value)));
}
@Override
public void onOPClicked(Post post) {
threadFragment.getThreadManager().showPostLinkables(post);
}
}

@ -16,9 +16,11 @@ import org.floens.chan.utils.ViewFlipperAnimations;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@ -75,26 +77,24 @@ public class ReplyFragment extends DialogFragment {
return reply;
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (threadManager == null) return;
getCaptcha();
}
@Override
public void onDestroy() {
super.onDestroy();
ReplyManager replyManager = ReplyManager.getInstance();
// Save the info into the draft when existing
if (shouldSaveDraft) {
public void onPause() {
super.onPause();
if (threadManager == null) return;
ReplyManager replyManager = ReplyManager.getInstance();
if (shouldSaveDraft) {
draft.name = nameView.getText().toString();
draft.email = emailView.getText().toString();
draft.subject = subjectView.getText().toString();
@ -105,18 +105,34 @@ public class ReplyFragment extends DialogFragment {
replyManager.removeReplyDraft();
setFile(null);
}
replyManager.removeFileListener();
replyManager.removeFileListener();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
if (threadManager == null) {
closeReply();
return new View(inflater.getContext());
}
Dialog dialog = getDialog();
dialog.setTitle(R.string.reply);
Loadable l = threadManager.getLoadable();
Context context = inflater.getContext();
String title = l.isThreadMode() ?
context.getString(R.string.reply) + " /" + l.board + "/" + l.no :
context.getString(R.string.reply_to_board) + " /" + l.board + "/";
if (dialog == null) {
getActivity().getActionBar().setTitle(title);
} else {
dialog.setTitle(title);
}
setClosable(true);
// Setup the views with listeners
container = inflater.inflate(R.layout.reply_view, parent);
container = inflater.inflate(R.layout.reply_view, null);
flipper = (ViewFlipper)container.findViewById(R.id.reply_flipper);
nameView = (TextView)container.findViewById(R.id.reply_name);
@ -141,7 +157,7 @@ public class ReplyFragment extends DialogFragment {
if (page == 1) {
flipPage(0);
} else {
dismiss();
closeReply();
}
}
});
@ -185,25 +201,35 @@ public class ReplyFragment extends DialogFragment {
}
});
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (page == 1) {
flipPage(0);
} else if (page == 2) {
dismiss();
}
return true;
} else {
return false;
}
}
});
if (dialog != null) {
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (page == 1) {
flipPage(0);
} else if (page == 2) {
closeReply();
}
return true;
} else {
return false;
}
}
});
}
Reply draft = ReplyManager.getInstance().getReplyDraft();
if (TextUtils.isEmpty(draft.name)) {
draft.name = ChanApplication.getPreferences().getString("preference_default_name", "");
}
if (TextUtils.isEmpty(draft.email)) {
draft.email = ChanApplication.getPreferences().getString("preference_default_email", "");
}
nameView.setText(draft.name);
emailView.setText(draft.email);
subjectView.setText(draft.subject);
@ -213,12 +239,22 @@ public class ReplyFragment extends DialogFragment {
return container;
}
private void closeReply() {
if (getDialog() != null) {
dismiss();
} else {
getActivity().finish();
}
}
/**
* Set if the dialog is able to be closed, by pressing outside of the dialog, or something else.
*/
private void setClosable(boolean e) {
getDialog().setCanceledOnTouchOutside(e);
setCancelable(e);
if (getDialog() != null) {
getDialog().setCanceledOnTouchOutside(e);
setCancelable(e);
}
}
/**
@ -375,11 +411,12 @@ public class ReplyFragment extends DialogFragment {
setClosable(true);
flipPage(1);
getCaptcha();
captchaText.setText("");
} else if (response.isSuccessful) {
shouldSaveDraft = false;
Toast.makeText(getActivity(), R.string.reply_success, Toast.LENGTH_SHORT).show();
threadFragment.reload();
dismiss();
closeReply();
} else {
if (isVisible()) {
cancelButton.setEnabled(true);

@ -1,5 +1,6 @@
package org.floens.chan.fragment;
import org.floens.chan.ChanApplication;
import org.floens.chan.R;
import org.floens.chan.activity.AboutActivity;
@ -10,7 +11,6 @@ import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.widget.Toast;
public class SettingsFragment extends PreferenceFragment {
@ -42,7 +42,7 @@ public class SettingsFragment extends PreferenceFragment {
if (++clickCount >= 5) {
clickCount = 0;
SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences p = ChanApplication.getPreferences();
boolean e = !p.getBoolean("preference_br", false);
p.edit().putBoolean("preference_br", e).commit();
String m = e ? "Do a barrel roll" : "No barrel rolls this time";

@ -33,6 +33,7 @@ public class ThreadFragment extends Fragment implements ThreadListener {
private boolean shown = false;
private Loadable loadable;
private LoadView container;
private ListView listView;
public static ThreadFragment newInstance(BaseActivity activity) {
ThreadFragment fragment = new ThreadFragment();
@ -70,6 +71,10 @@ public class ThreadFragment extends Fragment implements ThreadListener {
if (container != null) {
container.setView(null);
}
if (listView != null) {
listView.setOnScrollListener(null);
}
}
public void startLoading(Loadable loadable) {
@ -92,7 +97,7 @@ public class ThreadFragment extends Fragment implements ThreadListener {
postAdapter = new PostAdapter(baseActivity, threadManager);
ListView listView = new ListView(baseActivity);
listView = new ListView(baseActivity);
listView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
listView.setAdapter(postAdapter);
listView.setSelectionFromTop(loadable.listViewIndex, loadable.listViewTop);
@ -104,9 +109,11 @@ public class ThreadFragment extends Fragment implements ThreadListener {
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
loadable.listViewIndex = view.getFirstVisiblePosition();
View v = view.getChildAt(0);
loadable.listViewTop = (v == null) ? 0 : v.getTop();
if (loadable != null) {
loadable.listViewIndex = view.getFirstVisiblePosition();
View v = view.getChildAt(0);
loadable.listViewTop = (v == null) ? 0 : v.getTop();
}
}
});
}
@ -132,7 +139,11 @@ public class ThreadFragment extends Fragment implements ThreadListener {
@Override
public void onPostClicked(Post post) {
baseActivity.onPostClicked(post);
if (loadable.isThreadMode()) {
threadManager.showPostLinkables(post);
} else {
baseActivity.onOPClicked(post);
}
}
@Override

@ -11,7 +11,6 @@ import org.floens.chan.net.ChanUrls;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
@ -224,7 +223,7 @@ public class BoardManager {
}
private SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(context);
return ChanApplication.getPreferences();
}
}

@ -3,13 +3,13 @@ package org.floens.chan.manager;
import java.util.ArrayList;
import java.util.Scanner;
import org.floens.chan.ChanApplication;
import org.floens.chan.adapter.PinnedAdapter;
import org.floens.chan.entity.Loadable;
import org.floens.chan.entity.Pin;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class PinnedManager {
private final ArrayList<Pin> list = new ArrayList<Pin>();
@ -130,7 +130,7 @@ public class PinnedManager {
}
private SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(context);
return ChanApplication.getPreferences();
}
}

@ -2,16 +2,23 @@ package org.floens.chan.manager;
import java.util.ArrayList;
import org.floens.chan.ChanApplication;
import org.floens.chan.R;
import org.floens.chan.entity.Loadable;
import org.floens.chan.entity.Post;
import org.floens.chan.entity.PostLinkable;
import org.floens.chan.fragment.PostPopupFragment;
import org.floens.chan.net.ThreadLoader;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
@ -29,15 +36,15 @@ import com.android.volley.VolleyError;
* This manages some things like pages, starting and stopping of loading etc.
*/
public class ThreadManager {
private final Context context;
private final Activity activity;
private final ThreadLoader threadLoader;
private final ThreadManager.ThreadListener threadListener;
private Loadable loadable;
private boolean endOfLine = false;
private final SparseArray<Post> postsById = new SparseArray<Post>();
public ThreadManager(Context context, final ThreadListener listener) {
this.context = context;
public ThreadManager(Activity context, final ThreadListener listener) {
this.activity = context;
threadListener = listener;
threadLoader = new ThreadLoader(new ThreadLoader.ThreadLoaderListener() {
@ -57,6 +64,10 @@ public class ThreadManager {
});
}
public boolean hasThread() {
return loadable != null;
}
public Post getPostById(int id) {
return postsById.get(id);
}
@ -112,7 +123,7 @@ public class ThreadManager {
}
public void onPostLongClicked(final Post post) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setItems(R.array.post_options, new DialogInterface.OnClickListener() {
@Override
@ -142,14 +153,14 @@ public class ThreadManager {
String errorMessage = "";
if ((error instanceof NoConnectionError) || (error instanceof NetworkError)) {
errorMessage = context.getString(R.string.thread_load_failed_network);
errorMessage = activity.getString(R.string.thread_load_failed_network);
} else if (error instanceof ServerError) {
errorMessage = context.getString(R.string.thread_load_failed_server);
errorMessage = activity.getString(R.string.thread_load_failed_server);
} else {
errorMessage = context.getString(R.string.thread_load_failed_parsing);
errorMessage = activity.getString(R.string.thread_load_failed_parsing);
}
TextView view = new TextView(context);
TextView view = new TextView(activity);
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
view.setText(errorMessage);
view.setTextSize(24f);
@ -159,7 +170,7 @@ public class ThreadManager {
}
private void copyText(String comment) {
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("post text", comment);
clipboard.setPrimaryClip(clip);
}
@ -187,7 +198,7 @@ public class ThreadManager {
text += "\nCountry: " + post.countryName;
}
AlertDialog dialog = new AlertDialog.Builder(context)
AlertDialog dialog = new AlertDialog.Builder(activity)
.setTitle(R.string.post_info)
.setMessage(text)
.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@ -200,6 +211,109 @@ public class ThreadManager {
dialog.show();
}
/**
* When the user clicks a post:
* a. when there's one linkable, open the linkable.
* b. when there's more than one linkable, show the user multiple options to select from.
* @param post The post that was clicked.
*/
public void showPostLinkables(Post post) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
final ArrayList<PostLinkable> linkables = post.linkables;
if (linkables.size() > 0) {
if (linkables.size() == 1) {
handleLinkableSelected(linkables.get(0));
} else {
String[] keys = new String[linkables.size()];
for (int i = 0; i < linkables.size(); i++) {
keys[i] = linkables.get(i).key;
}
builder.setItems(keys, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handleLinkableSelected(linkables.get(which));
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
}
/**
* Handle when a linkable has been clicked.
* @param linkable the selected linkable.
*/
private void handleLinkableSelected(final PostLinkable linkable) {
if (linkable.type == PostLinkable.Type.QUOTE) {
showPostPopup(linkable);
} else if (linkable.type == PostLinkable.Type.LINK) {
if (ChanApplication.getPreferences().getBoolean("preference_open_link_confirmation", true)) {
AlertDialog dialog = new AlertDialog.Builder(activity)
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
openLink(linkable);
}
})
.setTitle(R.string.open_link_confirmation)
.setMessage(linkable.value)
.create();
dialog.show();
} else {
openLink(linkable);
}
}
}
/**
* When a linkable to a post has been clicked,
* show a dialog with the referenced post in it.
* @param linkable the clicked linkable.
*/
private void showPostPopup(PostLinkable linkable) {
String value = linkable.value;
Post post = null;
try {
// Get post id
String[] splitted = value.split("#p");
if (splitted.length == 2) {
int id = Integer.parseInt(splitted[1]);
post = getPostById(id);
if (post != null) {
PostPopupFragment popup = PostPopupFragment.newInstance(post, this);
FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
ft.add(popup, "postPopup");
ft.commitAllowingStateLoss();
}
}
} catch(NumberFormatException e) {
e.printStackTrace();
}
}
/**
* Open an url.
* @param linkable Linkable with an url.
*/
private void openLink(PostLinkable linkable) {
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(linkable.value)));
}
public interface ThreadListener {
public void onThreadLoaded(ArrayList<Post> result);
public void onThreadLoadError(VolleyError error);

@ -180,7 +180,7 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
isBuild = true;
Resources resources = context.getResources();
int postPadding = resources.getDimensionPixelSize(R.dimen.post_padding);
int commentPadding = resources.getDimensionPixelSize(R.dimen.post_comment_padding);
int textPadding = resources.getDimensionPixelSize(R.dimen.post_text_padding);
int iconWidth = resources.getDimensionPixelSize(R.dimen.post_icon_width);
int iconHeight = resources.getDimensionPixelSize(R.dimen.post_icon_height);
@ -213,7 +213,7 @@ public class PostView extends LinearLayout implements View.OnClickListener, View
LinearLayout right = new LinearLayout(context);
right.setOrientation(VERTICAL);
right.setPadding(postPadding, postPadding, postPadding, postPadding);
right.setPadding(commentPadding, commentPadding, commentPadding, commentPadding);
LinearLayout header = new LinearLayout(context);
header.setOrientation(HORIZONTAL);

Loading…
Cancel
Save