diff --git a/app/app.iml b/app/app.iml index 5f801ea..e4975bb 100644 --- a/app/app.iml +++ b/app/app.iml @@ -65,27 +65,21 @@ - - + - - - + + - - - - - - + + @@ -100,13 +94,15 @@ + - + + + + - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 6c7dca5..f266988 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,9 +13,9 @@ beta Bamiyan 10.x Ujimatsu */ def VERSION_MAJOR = 0 -def VERSION_MINOR = 3 -def VERSION_PATCH = 3 -def VERSION_NAME = 'Dragonforce' +def VERSION_MINOR = 4 +def VERSION_PATCH = 0 +def VERSION_NAME = 'Bamiyan' repositories { mavenCentral() @@ -96,13 +96,14 @@ retrolambda { dependencies { compile project(':bhavaagra') - compile 'com.android.support:appcompat-v7:23.1.0' - compile 'com.android.support:support-v4:23.1.0' + compile 'com.android.support:appcompat-v7:23.1.1' + compile 'com.android.support:support-v4:23.1.1' //compile 'com.android.support:multidex:1.0.1' compile 'org.twitter4j:twitter4j:4.0.4' compile 'org.twitter4j:twitter4j-stream:4.0.4' compile 'org.twitter4j:twitter4j-media-support:4.0.4' compile 'org.twitter4j:twitter4j-http2-support:4.0.4' + compile 'com.twitter:twitter-text:1.6.1' compile 'com.google.guava:guava:18.0' compile 'io.realm:realm-android:0.84.0' compile 'joda-time:joda-time:2.8' diff --git a/app/src/main/java/org/kb10uy/tencocoa/HomeTimeLineFragment.java b/app/src/main/java/org/kb10uy/tencocoa/HomeTimeLineFragment.java index cfa6410..4925d92 100644 --- a/app/src/main/java/org/kb10uy/tencocoa/HomeTimeLineFragment.java +++ b/app/src/main/java/org/kb10uy/tencocoa/HomeTimeLineFragment.java @@ -23,6 +23,7 @@ import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.AnimationUtils; +import android.widget.AbsListView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; @@ -63,6 +64,10 @@ public class HomeTimeLineFragment extends Fragment { private long currentUserId; private SharedPreferences pref; private Drawable mFavoriteIcon; + private LinearLayout mUpdatePopup; + private TextView mUpdatePopupText; + private boolean mHasNewTweet = false; + private int mRestNewTweet = 0, mLastTotal = 0; public HomeTimeLineFragment() { // Required empty public constructor @@ -99,8 +104,26 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, mPopupCaption = (TextView) view.findViewById(R.id.HomeTimeLineTextViewCaption); mPopupDescription = (TextView) view.findViewById(R.id.HomeTimeLineTextViewDescription); mPopup = (LinearLayout) view.findViewById(R.id.HomeTimeLinePopup); + mUpdatePopupText = (TextView) view.findViewById(R.id.HomeTimeLineUpdatePopupText); + mUpdatePopup = (LinearLayout) view.findViewById(R.id.HomeTimeLineUpdatePopup); view.getContext().getTheme().resolveAttribute(R.attr.colorRetweetBackground, mRewteetBackgroundValue, true); + mListView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + } + + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + if (firstVisibleItem < mRestNewTweet) { + rewriteNewTweets(--mRestNewTweet); + if (mRestNewTweet == 0) { + popdownNewTweets(); + mHasNewTweet = false; + } + } + } + }); return view; } @@ -229,7 +252,22 @@ public void onHomeTimeLineStreamingStatus(Status status) { tstatus.favorite(); } realm.close(); - mHandler.post(() -> mTimeLineAdapter.add(tstatus)); + int prevCount = mTimeLineAdapter.getCount(); + int y = mListView.getChildAt(0).getTop(); + int item = mListView.getFirstVisiblePosition(); + + mHandler.post(() -> { + mTimeLineAdapter.add(tstatus); + if (item != 0 || y != 0) { + if (!mHasNewTweet) { + mHasNewTweet = true; + popupNewTweets(); + mRestNewTweet = 0; + } + rewriteNewTweets(++mRestNewTweet); + mListView.setSelectionFromTop(item + 1, y); + } + }); } public void addRestStatuses(List statuses) { @@ -300,6 +338,22 @@ private void showNotificationPopup(int iconResource, User source, String caption set.start(); } + private void popupNewTweets() { + AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(getActivity(), R.animator.new_tweet_popup); + set.setTarget(mUpdatePopup); + set.start(); + } + + private void popdownNewTweets() { + AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(getActivity(), R.animator.new_tweet_popdown); + set.setTarget(mUpdatePopup); + set.start(); + } + + private void rewriteNewTweets(int count) { + mUpdatePopupText.setText(getString(R.string.popup_update_count, count)); + } + public void clearStatuses() { mTimeLineAdapter.clear(); } diff --git a/app/src/main/java/org/kb10uy/tencocoa/MainActivity.java b/app/src/main/java/org/kb10uy/tencocoa/MainActivity.java index 6fe24f3..bca6308 100644 --- a/app/src/main/java/org/kb10uy/tencocoa/MainActivity.java +++ b/app/src/main/java/org/kb10uy/tencocoa/MainActivity.java @@ -97,6 +97,7 @@ public class MainActivity @Override protected void onCreate(Bundle savedInstanceState) { + PreferenceManager.setDefaultValues(this, R.xml.settings_default, true); pref = PreferenceManager.getDefaultSharedPreferences(this); checkTheme(); super.onCreate(savedInstanceState); @@ -243,7 +244,7 @@ public boolean onOptionsItemSelected(MenuItem item) { @Override public boolean dispatchKeyEvent(KeyEvent event) { int kc = event.getKeyCode(); - if (event.getAction()==KeyEvent.ACTION_DOWN) { + if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (kc) { case KeyEvent.KEYCODE_BACK: boolean fin = mBackDoubleTapHelper.onTap(); diff --git a/app/src/main/java/org/kb10uy/tencocoa/NewStatusDialogFragment.java b/app/src/main/java/org/kb10uy/tencocoa/NewStatusDialogFragment.java index 5e9c689..e15fef7 100644 --- a/app/src/main/java/org/kb10uy/tencocoa/NewStatusDialogFragment.java +++ b/app/src/main/java/org/kb10uy/tencocoa/NewStatusDialogFragment.java @@ -2,16 +2,25 @@ import android.app.Activity; import android.app.Dialog; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.v4.app.DialogFragment; import android.net.Uri; import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; +import com.bumptech.glide.Glide; +import com.twitter.Extractor; + import org.kb10uy.bhavaagra.BhavaAgra; import org.kb10uy.bhavaagra.Rhapsody; import org.kb10uy.tencocoa.model.TencocoaHelper; @@ -31,6 +40,10 @@ public class NewStatusDialogFragment extends DialogFragment { private Status replyToStatus; private List mSelectedImage; private SharedPreferences pref; + private LinearLayout mImagesLinearLayout; + private String mCurrentText = ""; + private EditText mStatusText; + private TextView mTextLength; public static NewStatusDialogFragment newInstance() { return new NewStatusDialogFragment(); @@ -60,10 +73,12 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { final Dialog dialog = new Dialog(getActivity()); dialog.getWindow().requestFeature(STYLE_NO_TITLE); dialog.setContentView(R.layout.fragment_new_status_dialog); - EditText teStatus = (EditText) dialog.findViewById(R.id.NewStatusDialogFragmentStatusText); + mStatusText = (EditText) dialog.findViewById(R.id.NewStatusDialogFragmentStatusText); + mTextLength = (TextView) dialog.findViewById(R.id.NewStatusDialogFragmentLengthText); + mImagesLinearLayout = (LinearLayout) dialog.findViewById(R.id.NewStatusDialogFragmentImages); dialog.findViewById(R.id.NewStatusDialogFragmentButtonUpdateStatus).setOnClickListener(v -> { - String text = teStatus.getText().toString(); + String text = mStatusText.getText().toString(); dismiss(); updateStatus(text); }); @@ -80,6 +95,24 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { ); }); + mStatusText.addTextChangedListener(new TextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + mCurrentText = mStatusText.getText().toString(); + recalculateLength(mCurrentText); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + mSelectedImage = new ArrayList<>(); Bundle arguments = getArguments(); if (arguments == null) return dialog; @@ -87,13 +120,15 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { if (reply != null) { replyToStatus = reply; String template = TencocoaHelper.createReplyTemplate(new TencocoaStatus(reply)); - teStatus.setText(template); - teStatus.setSelection(template.length()); + mStatusText.setText(template); + mStatusText.setSelection(template.length()); ((TextView) dialog.findViewById(R.id.NewStatusDialogFragmentTitle)).setText(getString(R.string.label_dialog_new_status_reply)); ((TextView) dialog.findViewById(R.id.NewStatusDialogFragmentReplyUserName)).setText(reply.getUser().getName()); ((TextView) dialog.findViewById(R.id.NewStatusDialogFragmentReplyText)).setText(reply.getText()); dialog.findViewById(R.id.NewStatusDialogFragmentReply).setVisibility(View.VISIBLE); } + + recalculateLength(""); return dialog; } @@ -104,6 +139,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { case INTENT_CAMERA: if (resultCode == Activity.RESULT_OK) { mSelectedImage = BhavaAgra.parse(data); + updateImageList(); } return; default: @@ -139,6 +175,43 @@ public void onDetach() { mListener = null; } + + private void updateImageList() { + if (mSelectedImage.size() == 0) { + mImagesLinearLayout.setVisibility(View.GONE); + mCurrentText = mStatusText.getText().toString(); + recalculateLength(mCurrentText); + return; + } + + mImagesLinearLayout.setVisibility(View.VISIBLE); + mImagesLinearLayout.removeAllViews(); + LayoutInflater inflater = (LayoutInflater) getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + for (Uri uri : mSelectedImage) { + View av = inflater.inflate(R.layout.item_status_image, mImagesLinearLayout, false); + ImageView imv = (ImageView) av.findViewById(R.id.StatusItemImageItem); + Glide.with(getActivity()).load(uri).into(imv); + mImagesLinearLayout.addView(av); + } + mCurrentText = mStatusText.getText().toString(); + recalculateLength(mCurrentText); + } + + private void recalculateLength(String s) { + int rawLength = s.trim().length(); + Extractor ext = new Extractor(); + List urls = ext.extractURLs(s); + for (String u : urls) rawLength -= (u.length() - 23); + if (mSelectedImage.size() != 0) rawLength += 25; + + StringBuilder sb = new StringBuilder(); + sb.append(rawLength); + sb.append("/"); + sb.append(140); + + mTextLength.setText(sb.toString()); + } + public interface NewStatusDialogFragmentInteractionListener { void applyUpdateStatus(String status, List mediaUris); diff --git a/app/src/main/java/org/kb10uy/tencocoa/TencocoaWritePermissionService.java b/app/src/main/java/org/kb10uy/tencocoa/TencocoaWritePermissionService.java index 8b29787..a5a052e 100644 --- a/app/src/main/java/org/kb10uy/tencocoa/TencocoaWritePermissionService.java +++ b/app/src/main/java/org/kb10uy/tencocoa/TencocoaWritePermissionService.java @@ -3,13 +3,16 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.Service; +import android.content.ContentResolver; import android.content.Intent; import android.content.SharedPreferences; +import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; import android.os.IBinder; import android.preference.PreferenceManager; +import android.provider.MediaStore; import android.widget.Toast; import org.kb10uy.tencocoa.model.TwitterAccountInformation; @@ -95,23 +98,37 @@ protected String doInBackground(StatusUpdate... params) { if (mPendingMediaUris.size() >= 0) { List media = new ArrayList<>(); for (Uri u : mPendingMediaUris) { - media.add(mTwitter.uploadMedia(new File(u.toString()))); + String path = ""; + if (u.getScheme().equals("content")) { + ContentResolver contentResolver = getApplicationContext().getContentResolver(); + Cursor cursor = contentResolver.query(u, new String[]{MediaStore.MediaColumns.DATA}, null, null, null); + if (cursor != null) { + cursor.moveToFirst(); + path = cursor.getString(0); + cursor.close(); + } + } else { + path = u.getPath(); + } + media.add(mTwitter.uploadMedia(new File(path))); } mPendingMediaUris.clear(); - target.setMediaIds(TwitterHelper.convertMediaIds(media)); + long[] ids = TwitterHelper.convertMediaIds(media); + target.setMediaIds(ids); } mTwitter.tweets().updateStatus(target); return ""; } catch (TwitterException e) { e.printStackTrace(); - return e.getErrorMessage(); + mPendingMediaUris.clear(); + return e.getMessage(); } } @Override protected void onPostExecute(String result) { super.onPostExecute(result); - if (result.equals("")) { + if (result != null && result.equals("")) { showNotification(getString(R.string.notification_update_status_success), getString(R.string.notification_update_status_success)); } else { StringBuilder sb = new StringBuilder(); diff --git a/app/src/main/java/org/kb10uy/tencocoa/views/ImageViewerActivity.java b/app/src/main/java/org/kb10uy/tencocoa/views/ImageViewerActivity.java index 1a5b31b..3b6217b 100644 --- a/app/src/main/java/org/kb10uy/tencocoa/views/ImageViewerActivity.java +++ b/app/src/main/java/org/kb10uy/tencocoa/views/ImageViewerActivity.java @@ -36,13 +36,17 @@ protected void onCreate(Bundle savedInstanceState) { mAttacher = new PhotoViewAttacher(mImageView); mAttacher.setZoomable(true); mAttacher.setMaximumScale(4); - Glide.with(this).load(targetUri).into(new GlideDrawableImageViewTarget(mImageView) { - @Override - public void onResourceReady(GlideDrawable resource, GlideAnimation animation) { - super.onResourceReady(resource, animation); - mAttacher.update(); - } - }); + Glide + .with(this) + .load(targetUri) + /*.placeholder(R.drawable.placeholder)*/ + .into(new GlideDrawableImageViewTarget(mImageView) { + @Override + public void onResourceReady(GlideDrawable resource, GlideAnimation animation) { + super.onResourceReady(resource, animation); + mAttacher.update(); + } + }); setListeners(); } diff --git a/app/src/main/res/animator/new_tweet_popdown.xml b/app/src/main/res/animator/new_tweet_popdown.xml new file mode 100644 index 0000000..76691a3 --- /dev/null +++ b/app/src/main/res/animator/new_tweet_popdown.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/animator/new_tweet_popup.xml b/app/src/main/res/animator/new_tweet_popup.xml new file mode 100644 index 0000000..7811703 --- /dev/null +++ b/app/src/main/res/animator/new_tweet_popup.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/drawable-hdpi/ic_launcher.png index 5bccc25..64a4d31 100644 Binary files a/app/src/main/res/drawable-hdpi/ic_launcher.png and b/app/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 4813287..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/drawable-xhdpi/ic_launcher.png index ed77725..5fb86ed 100644 Binary files a/app/src/main/res/drawable-xhdpi/ic_launcher.png and b/app/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxhdpi/ic_launcher.png index ead1f21..d19dd80 100644 Binary files a/app/src/main/res/drawable-xxhdpi/ic_launcher.png and b/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_launcher.png b/app/src/main/res/drawable-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..9ee6379 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable/placeholder.png b/app/src/main/res/drawable/placeholder.png new file mode 100644 index 0000000..a79fb04 Binary files /dev/null and b/app/src/main/res/drawable/placeholder.png differ diff --git a/app/src/main/res/layout-sw600dp/fragment_new_status_dialog.xml b/app/src/main/res/layout-sw600dp/fragment_new_status_dialog.xml index ecefe7e..2f1ee52 100644 --- a/app/src/main/res/layout-sw600dp/fragment_new_status_dialog.xml +++ b/app/src/main/res/layout-sw600dp/fragment_new_status_dialog.xml @@ -46,6 +46,24 @@ android:ems="10" android:gravity="top" android:inputType="textMultiLine" /> + + + + + + + + diff --git a/app/src/main/res/layout/fragment_new_status_dialog.xml b/app/src/main/res/layout/fragment_new_status_dialog.xml index db12748..0544898 100644 --- a/app/src/main/res/layout/fragment_new_status_dialog.xml +++ b/app/src/main/res/layout/fragment_new_status_dialog.xml @@ -47,6 +47,25 @@ android:ems="10" android:gravity="top" android:inputType="textMultiLine" /> + + + + + + Tencocoa disconnected UserStream. Downloaded image successfully. + Sending your tweet... Tweeted successfully. Failed to tweet: Favorited successfully. @@ -96,6 +97,8 @@ Retweeted mention by %1$s Retweeted mention by %1$s + %1$d件 new tweets + Faved by %1$s: %2$s Unfaved by %1$s: %2$s Followed by %1$s(@%2$s) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 3d61219..3ae8c43 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -74,6 +74,7 @@ UserStreamから切断しました。 画像のダウンロードが終了しました。 + ツイートを送信しています… ツイートに成功しました。 ツイートに失敗しました。: お気に入りに成功しました。 @@ -95,6 +96,8 @@ %1$sさんに自分宛てメンションをふぁぼられました %1$sさんに自分宛てメンションをリツイートされました + %1$d件の新着ツイート + %1$sさんにふぁぼられました: %2$s %1$sさんにあんふぁぼられました: %2$s %1$s(@%2$s)さんにフォローされました diff --git a/app/src/main/res/xml/settings_default.xml b/app/src/main/res/xml/settings_default.xml new file mode 100644 index 0000000..da41b9a --- /dev/null +++ b/app/src/main/res/xml/settings_default.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/version.properties b/app/version.properties index 7cdef20..79c7cca 100644 --- a/app/version.properties +++ b/app/version.properties @@ -1,2 +1,2 @@ -#Sun Nov 15 00:46:03 JST 2015 -VERSION_CODE=198 +#Sun Jan 10 20:25:33 JST 2016 +VERSION_CODE=262 diff --git a/bhavaagra/bhavaagra.iml b/bhavaagra/bhavaagra.iml index b05a06d..3f06060 100644 --- a/bhavaagra/bhavaagra.iml +++ b/bhavaagra/bhavaagra.iml @@ -65,22 +65,15 @@ + - - - + + - - - - - - - @@ -91,7 +84,7 @@ - + \ No newline at end of file