aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java
diff options
context:
space:
mode:
authorrhenium <rhenium@rhe.jp>2015-03-10 05:09:03 +0900
committerrhenium <rhenium@rhe.jp>2015-03-10 05:09:03 +0900
commita06fd2a877e440ad70634ccefef2f7032677ccb2 (patch)
tree008efd1da51fe754d012fa76ec03264dc70529bf /app/src/main/java
parente646bf319de9a5f64af0c58a8a5f6f30034a3a47 (diff)
downloadSmileEssence-a06fd2a877e440ad70634ccefef2f7032677ccb2.tar.gz
Migrate to Gradle
Diffstat (limited to 'app/src/main/java')
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/Application.java45
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/IntentRouter.java294
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditCommandActivity.java194
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditExtractionActivity.java245
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditTabActivity.java174
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditTemplateActivity.java245
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/activity/LicenseActivity.java104
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/activity/MainActivity.java893
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/activity/OAuthActivity.java126
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/activity/SettingActivity.java64
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/Command.java180
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenHashtagDialog.java71
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenSearch.java74
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenTemplateList.java66
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenURL.java70
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenUserDetail.java95
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenUserList.java68
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandPasteToPost.java71
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandSaveAsTemplate.java70
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandSearchOnTwitter.java68
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/IConfirmable.java33
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommand.java52
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandClipboard.java68
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandSearchOnGoogle.java67
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandShare.java70
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandTofuBuster.java79
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommand.java72
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandInsert.java71
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandMakeAnonymous.java69
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandMorse.java70
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandUseTemplate.java54
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandZekamashi.java82
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommand.java57
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandAddToIgnore.java66
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandAddToReply.java67
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandClipboard.java68
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandCongratulate.java114
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandCopy.java67
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandFavAndRT.java76
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandMakeAnonymous.java97
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandNanigaja.java105
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenInBrowser.java64
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenQuoteDialog.java67
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenTalkView.java73
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandReplyToAll.java78
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandReview.java67
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandSearchOnGoogle.java67
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandShare.java70
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandTextQuote.java71
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandTofuBuster.java79
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandURLQuote.java69
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommand.java52
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandAddToReply.java67
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandBlock.java72
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandIntroduce.java68
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenAclog.java64
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenFavstar.java64
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenTwilog.java64
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandReply.java70
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandReportForSpam.java72
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandSendMessage.java73
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandUnblock.java72
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/data/CommandSettingCache.java70
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/data/DirectMessageCache.java98
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/data/FavoriteCache.java99
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/data/ImageCache.java101
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/data/StatusCache.java108
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/data/UserCache.java105
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/data/UserListCache.java79
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/entity/Account.java69
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/entity/CommandSetting.java70
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/entity/ExtractionWord.java85
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/entity/SearchQuery.java88
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/entity/Template.java88
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/logging/Logger.java62
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/notification/NotificationType.java31
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/notification/Notificator.java169
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/preference/AppPreferenceHelper.java42
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/preference/SharedPreferenceHelper.java128
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/preference/UserPreferenceHelper.java155
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/OAuthSession.java88
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/StatusFilter.java67
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/TweetBuilder.java123
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/TwitterApi.java79
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/UserStreamListener.java334
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/AccessTokenTask.java62
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/BlockIDsTask.java83
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/BlockTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DeleteMessageTask.java85
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DeleteStatusTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DirectMessagesTask.java102
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/FavoriteTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/FollowTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/GetUserListsTask.java73
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/HomeTimelineTask.java104
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/MentionsTimelineTask.java104
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/MutesIDsTask.java83
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ReportForSpamTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/RequestTokenTask.java59
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/RetweetTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SearchTask.java113
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SendMessageTask.java87
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SentDirectMessagesTask.java102
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowDirectMessageTask.java73
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowFriendshipTask.java77
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowStatusTask.java73
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowUserTask.java89
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/TweetTask.java167
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/TwitterTask.java43
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnblockTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnfavoriteTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnfollowTask.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UserListStatusesTask.java87
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UserTimelineTask.java88
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/util/TwitterUtils.java346
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapOptimizer.java144
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapThumbnailTask.java80
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapURLTask.java91
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/IntentUtils.java98
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/Morse.java156
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/NameStyles.java54
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/NetworkHelper.java53
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/StringUtils.java63
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/Themes.java82
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/util/UIHandler.java79
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/CustomListFragment.java189
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/HistoryFragment.java58
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/HomeFragment.java136
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/MentionsFragment.java116
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/MessagesFragment.java119
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/PostFragment.java449
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/SearchFragment.java407
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/SettingFragment.java212
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/TextFragment.java59
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/UserListFragment.java242
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/CustomListAdapter.java209
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/EventListAdapter.java39
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/MessageListAdapter.java125
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/PageListAdapter.java207
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/PostState.java232
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/SearchListAdapter.java93
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/StatusListAdapter.java132
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ChooseTemplateDialogFragment.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ConfirmDialogFragment.java142
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/DialogHelper.java108
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/DisposeDialog.java56
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/EditTextDialogFragment.java98
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/HashtagDialogFragment.java100
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MenuDialogFragment.java79
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MessageDetailDialogFragment.java283
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MessageMenuDialogFragment.java170
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/PostMenuDialogFragment.java104
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/QuoteDialogFragment.java113
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ReviewDialogFragment.java141
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SearchOnGoogleDialogFragment.java146
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectImageDialogFragment.java143
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectSearchQueryDialogFragment.java115
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectUserListDialogFragment.java84
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SendMessageDialogFragment.java182
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SimpleDialogFragment.java88
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/StatusDetailDialogFragment.java392
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/StatusMenuDialogFragment.java171
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/TalkChainDialogFragment.java153
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/UserDetailDialogFragment.java527
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/UserMenuDialogFragment.java133
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/view/listener/ListItemClickListener.java71
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/CheckBoxModel.java87
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EditableCheckBoxModel.java134
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EnumEvent.java58
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EventViewModel.java201
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/IViewModel.java37
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/MessageViewModel.java215
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/StatusViewModel.java497
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/UserListListAdapter.java69
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/UserViewModel.java140
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/menu/MainActivityMenuHelper.java157
176 files changed, 20560 insertions, 0 deletions
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/Application.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/Application.java
new file mode 100644
index 00000000..9a513dc0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/Application.java
@@ -0,0 +1,45 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence;
+
+public class Application extends com.activeandroid.app.Application
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private int themeIndex;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public int getThemeIndex()
+ {
+ return themeIndex;
+ }
+
+ public void setThemeIndex(int themeIndex)
+ {
+ this.themeIndex = themeIndex;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/IntentRouter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/IntentRouter.java
new file mode 100644
index 00000000..b490bb10
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/IntentRouter.java
@@ -0,0 +1,294 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.CommandOpenUserDetail;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.UIHandler;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.StatusDetailDialogFragment;
+import twitter4j.Status;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class IntentRouter
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String TWITTER_HOST = "twitter.com";
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static void onNewIntent(MainActivity activity, Intent intent)
+ {
+ Logger.debug("IntentRouter:onNewIntent");
+ Uri uri = intent.getData();
+ if(uri != null)
+ {
+ onUriIntent(activity, uri);
+ }
+ else if(intent.getAction() != null)
+ {
+ switch(intent.getAction())
+ {
+ case Intent.ACTION_SEND:
+ {
+ if(intent.getType().equals("text/plain"))
+ {
+ Bundle extra = intent.getExtras();
+ if(extra != null)
+ {
+ String text = getText(extra);
+ openPostPage(activity, text);
+ }
+ }
+ else
+ {
+ Matcher matcher = Pattern.compile("image/.+").matcher(intent.getType());
+ if(matcher.find())
+ {
+ Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
+ openPostPageWithImage(activity, imageUri);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ private static String getText(Bundle extra)
+ {
+ StringBuilder builder = new StringBuilder();
+ if(!TextUtils.isEmpty(extra.getCharSequence(Intent.EXTRA_SUBJECT)))
+ {
+ builder.append(extra.getCharSequence(Intent.EXTRA_SUBJECT)).append(" ");
+ }
+ builder.append(extra.getCharSequence(Intent.EXTRA_TEXT));
+ return builder.toString();
+ }
+
+ private static String getText(Uri uri)
+ {
+ String text = "";
+ String url = "";
+ if(uri.getQueryParameter("text") != null)
+ {
+ text = uri.getQueryParameter("text").replaceAll("\\+", " ");
+ }
+ else if(uri.getQueryParameter("status") != null)
+ {
+ text = uri.getQueryParameter("status").replaceAll("\\+", " ");
+ }
+
+ if(uri.getQueryParameter("url") != null)
+ {
+ url = uri.getQueryParameter("url");
+ }
+ return text + " " + url;
+ }
+
+ private static void onUriIntent(MainActivity activity, Uri uri)
+ {
+ Logger.debug(uri.toString());
+ if(isPostIntent(uri))
+ {
+ String str = getText(uri);
+ openPostPage(activity, str);
+ }
+ else if(isStatusIntent(uri))
+ {
+ long id = getStatusID(uri);
+ showStatusDialog(activity, id);
+ }
+ else if(isUserIntent(uri))
+ {
+ String screenName = getScreenName(uri);
+ showUserDialog(activity, screenName);
+ }
+ }
+
+ private static String getScreenName(Uri uri)
+ {
+ String screenName;
+ if(uri.getQueryParameter("screen_name") != null)
+ {
+ screenName = uri.getQueryParameter("screen_name");
+ }
+ else
+ {
+ String[] arrayOfString = uri.toString().split("/");
+ screenName = arrayOfString[arrayOfString.length - 1];
+ }
+ return screenName;
+ }
+
+ private static long getStatusID(Uri uri)
+ {
+ String str = "-1";
+ String[] arrayOfString = uri.toString().split("/");
+ for(int i = 0; i < arrayOfString.length; i++)
+ {
+ if(arrayOfString[i].startsWith("status"))
+ {
+ str = arrayOfString[(i + 1)];
+ break;
+ }
+ }
+ return Long.parseLong(str);
+ }
+
+ private static boolean isPostIntent(Uri uri)
+ {
+ if(uri.getHost().equals(TWITTER_HOST))
+ {
+ if(uri.getPath().equals("/share"))
+ {
+ return true;
+ }
+ else
+ {
+ String[] arr = uri.toString().split("/");
+ for(String s : arr)
+ {
+ if(s.startsWith("tweet") || s.startsWith("home"))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean isStatusIntent(Uri uri)
+ {
+ if(uri.getHost().equals(TWITTER_HOST))
+ {
+ String[] arr = uri.toString().split("/");
+ for(String s : arr)
+ {
+ if(s.equals("status") || s.equals("statuses"))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean isUserIntent(Uri uri)
+ {
+ if(uri.getHost().equals(TWITTER_HOST))
+ {
+ if(uri.getQueryParameter("screen_name") != null)
+ {
+ return true;
+ }
+
+ String[] arrayOfString = uri.toString().split("/");
+ if(arrayOfString.length == 4 && uri.getQuery() == null)
+ {
+ return true;
+ }
+ else if(arrayOfString.length > 4)
+ {
+ if(arrayOfString[3].equals("#!") && uri.getQuery() == null)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static void showStatusDialog(final MainActivity activity, long id)
+ {
+ if(id != -1)
+ {
+ TwitterUtils.tryGetStatus(activity.getCurrentAccount(), id, new TwitterUtils.StatusCallback()
+ {
+ @Override
+ public void success(Status status)
+ {
+ StatusDetailDialogFragment fragment = new StatusDetailDialogFragment();
+ fragment.setStatusID(status.getId());
+ DialogHelper.showDialog(activity, fragment);
+ }
+
+ @Override
+ public void error()
+ {
+ Notificator.publish(activity, R.string.error_intent_status_cannot_load, NotificationType.ALERT);
+ }
+ });
+ }
+ else
+ {
+ Notificator.publish(activity, R.string.error_intent_status_cannot_load, NotificationType.ALERT);
+ }
+ }
+
+ private static void showUserDialog(MainActivity activity, String screenName)
+ {
+ CommandOpenUserDetail openUserDetail = new CommandOpenUserDetail(activity, screenName, activity.getCurrentAccount());
+ openUserDetail.execute();
+ }
+
+ private static void openPostPage(final MainActivity activity, final String str)
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ PostState.newState().beginTransaction().setText(str).commitWithOpen(activity);
+ }
+ }.post();
+ }
+
+ private static void openPostPageWithImage(final MainActivity activity, final Uri imageUri)
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ activity.openPostPageWithImage(imageUri);
+ }
+ }.post();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditCommandActivity.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditCommandActivity.java
new file mode 100644
index 00000000..82564c29
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditCommandActivity.java
@@ -0,0 +1,194 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.activity;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.NavUtils;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ListView;
+import net.lacolaco.smileessence.Application;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.status.StatusCommand;
+import net.lacolaco.smileessence.command.user.UserCommand;
+import net.lacolaco.smileessence.data.CommandSettingCache;
+import net.lacolaco.smileessence.entity.CommandSetting;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.util.Themes;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import net.lacolaco.smileessence.viewmodel.CheckBoxModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EditCommandActivity extends Activity
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private CustomListAdapter<CheckBoxModel> adapter;
+ private List<Command> editedCommands;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private CheckBoxModel[] getCheckBoxItems()
+ {
+ editedCommands = new ArrayList<>();
+ List<CheckBoxModel> checkBoxModels = new ArrayList<>();
+ List<CommandSetting> commandSettings = CommandSetting.getAll();
+ List<Command> commands = Command.getAllCommands(this);
+ for(Command command : commands)
+ {
+ if(command.getKey() < 0)
+ {
+ continue;
+ }
+ String text;
+ if(command instanceof StatusCommand)
+ {
+ text = String.format("Tweet : %s", command.getText());
+ }
+ else if(command instanceof UserCommand)
+ {
+ text = String.format("User : %s", command.getText());
+ }
+ else
+ {
+ continue;
+ }
+ editedCommands.add(command);
+ CommandSetting setting = null;
+ for(CommandSetting s : commandSettings)
+ {
+ if(command.getKey() == s.commandKey)
+ {
+ setting = s;
+ }
+ }
+ if(setting == null)
+ {
+ setting = new CommandSetting(command.getKey(), true);
+ setting.save();
+ }
+ CheckBoxModel checkBoxModel = new CheckBoxModel(text, setting.visibility);
+ checkBoxModels.add(checkBoxModel);
+ }
+ return checkBoxModels.toArray(new CheckBoxModel[checkBoxModels.size()]);
+ }
+
+ private ListView getListView()
+ {
+ return (ListView) findViewById(R.id.listview_edit_list);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ UserPreferenceHelper userPreferenceHelper = new UserPreferenceHelper(this);
+ setTheme(Themes.getTheme(((Application) getApplication()).getThemeIndex()));
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.layout_edit_list);
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ initializeViews();
+ Logger.debug("EditCommandActivity:onCreate");
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ MenuItem allOn = menu.add(Menu.NONE, R.id.menu_edit_command_all_on, Menu.NONE, "");
+ allOn.setTitle(R.string.actionbar_edit_command_all_on);
+ allOn.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ return true;
+ }
+
+ @Override
+ protected void onDestroy()
+ {
+ for(int i = 0; i < adapter.getCount(); i++)
+ {
+ CheckBoxModel checkBoxModel = (CheckBoxModel) adapter.getItem(i);
+ Command command = editedCommands.get(i);
+ CommandSetting commandSetting = CommandSetting.selectByKey(command.getKey());
+ commandSetting.visibility = checkBoxModel.isChecked();
+ commandSetting.save();
+ CommandSettingCache.getInstance().put(commandSetting);
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case R.id.menu_edit_command_all_on:
+ {
+ enableAll();
+ break;
+ }
+ case android.R.id.home:
+ {
+ NavUtils.navigateUpFromSameTask(this);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ private void enableAll()
+ {
+ adapter.setNotifiable(false);
+ for(int i = 0; i < adapter.getCount(); i++)
+ {
+ CheckBoxModel item = (CheckBoxModel) adapter.getItem(i);
+ item.setChecked(true);
+ }
+ adapter.setNotifiable(true);
+ adapter.notifyDataSetChanged();
+ updateListView();
+ }
+
+ private void initializeViews()
+ {
+ ListView listView = getListView();
+ adapter = new CustomListAdapter<>(this, CheckBoxModel.class);
+ listView.setAdapter(adapter);
+ adapter.addToTop(getCheckBoxItems());
+ adapter.update();
+ }
+
+ private void updateListView()
+ {
+ getListView().requestLayout();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditExtractionActivity.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditExtractionActivity.java
new file mode 100644
index 00000000..8f78d6fa
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditExtractionActivity.java
@@ -0,0 +1,245 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.activity;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.NavUtils;
+import android.text.TextUtils;
+import android.util.SparseBooleanArray;
+import android.view.*;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import net.lacolaco.smileessence.Application;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.entity.ExtractionWord;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.util.Themes;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.EditTextDialogFragment;
+
+import java.util.List;
+
+public class EditExtractionActivity extends Activity implements AdapterView.OnItemClickListener,
+ AbsListView.MultiChoiceModeListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private CustomListAdapter<ExtractionWord> adapter;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private ExtractionWord[] getExtractionWords()
+ {
+ List<ExtractionWord> all = ExtractionWord.getAll();
+ return all.toArray(new ExtractionWord[all.size()]);
+ }
+
+ private ListView getListView()
+ {
+ return (ListView) findViewById(R.id.listview_edit_list);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface Callback ---------------------
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu)
+ {
+ menu.clear();
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.edit_list, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu)
+ {
+ return false;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case R.id.menu_edit_list_delete:
+ {
+ deleteSelectedItems();
+ }
+ }
+ mode.finish();
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode)
+ {
+ }
+
+ // --------------------- Interface MultiChoiceModeListener ---------------------
+
+ @Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked)
+ {
+ }
+
+ // --------------------- Interface OnItemClickListener ---------------------
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id)
+ {
+ openEditExtractionWordDialog(position);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ setTheme(Themes.getTheme(((Application) getApplication()).getThemeIndex()));
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.layout_edit_list);
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ initializeViews();
+ Logger.debug("EditExtractionWordActivity:onCreate");
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ MenuItem add = menu.add(Menu.NONE, R.id.menu_edit_list_add, Menu.NONE, "");
+ add.setIcon(android.R.drawable.ic_menu_add);
+ add.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case R.id.menu_edit_list_add:
+ {
+ addNewExtractionWord();
+ break;
+ }
+ case android.R.id.home:
+ {
+ NavUtils.navigateUpFromSameTask(this);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void deleteSelectedItems()
+ {
+ SparseBooleanArray checkedItems = getListView().getCheckedItemPositions();
+ adapter.setNotifiable(false);
+ for(int i = adapter.getCount() - 1; i > -1; i--)
+ {
+ if(checkedItems.get(i))
+ {
+ ExtractionWord extractionWord = adapter.removeItem(i);
+ extractionWord.delete();
+ }
+ }
+ adapter.setNotifiable(true);
+ adapter.notifyDataSetChanged();
+ updateListView();
+ }
+
+ public void openEditExtractionWordDialog(int position)
+ {
+ final ExtractionWord extractionWord = (ExtractionWord) adapter.getItem(position);
+ EditTextDialogFragment dialogFragment = new EditTextDialogFragment()
+ {
+ @Override
+ public void onTextInput(String text)
+ {
+ if(TextUtils.isEmpty(text.trim()))
+ {
+ return;
+ }
+ extractionWord.text = text;
+ extractionWord.save();
+ adapter.notifyDataSetChanged();
+ updateListView();
+ }
+ };
+ dialogFragment.setParams(getString(R.string.dialog_title_edit), extractionWord.text);
+ DialogHelper.showDialog(this, dialogFragment);
+ }
+
+ private void addNewExtractionWord()
+ {
+ final ExtractionWord extractionWord = new ExtractionWord();
+ EditTextDialogFragment dialogFragment = new EditTextDialogFragment()
+ {
+ @Override
+ public void onTextInput(String text)
+ {
+ if(TextUtils.isEmpty(text.trim()))
+ {
+ return;
+ }
+ extractionWord.text = text;
+ extractionWord.save();
+ adapter.addToBottom(extractionWord);
+ adapter.notifyDataSetChanged();
+ updateListView();
+ }
+ };
+ dialogFragment.setParams(getString(R.string.dialog_title_add), "");
+ DialogHelper.showDialog(this, dialogFragment);
+ }
+
+ private void initializeViews()
+ {
+ ListView listView = getListView();
+ adapter = new CustomListAdapter<>(this, ExtractionWord.class);
+ listView.setAdapter(adapter);
+ adapter.addToTop(getExtractionWords());
+ adapter.update();
+ listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ listView.setOnItemClickListener(this);
+ listView.setMultiChoiceModeListener(this);
+ }
+
+ private void updateListView()
+ {
+ getListView().requestLayout();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditTabActivity.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditTabActivity.java
new file mode 100644
index 00000000..6b785bb8
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditTabActivity.java
@@ -0,0 +1,174 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.activity;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.NavUtils;
+import android.view.MenuItem;
+import android.widget.ListView;
+import net.lacolaco.smileessence.Application;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.util.Themes;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import net.lacolaco.smileessence.viewmodel.EditableCheckBoxModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EditTabActivity extends Activity
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private CustomListAdapter<EditableCheckBoxModel> adapter;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private EditableCheckBoxModel[] getCheckBoxItems()
+ {
+ List<EditableCheckBoxModel> models = new ArrayList<>();
+
+ EditableCheckBoxModel post = new EditableCheckBoxModel(getString(R.string.page_name_post));
+ post.setChecked(true).setInputText(String.valueOf(0)).setFreezing(true);
+ models.add(post);
+ EditableCheckBoxModel home = new EditableCheckBoxModel(getString(R.string.page_name_home));
+ home.setChecked(true).setInputText(String.valueOf(1)).setFreezing(true);
+ models.add(home);
+ EditableCheckBoxModel mentions = new EditableCheckBoxModel(getString(R.string.page_name_mentions));
+ mentions.setChecked(true).setInputText(String.valueOf(2)).setFreezing(true);
+ models.add(mentions);
+ EditableCheckBoxModel messages = new EditableCheckBoxModel(getString(R.string.page_name_messages));
+ messages.setChecked(getVisibility(R.string.key_page_messages_visibility))
+ .setInputText(String.valueOf(getPosition(R.string.key_page_messages_position, 3)));
+ models.add(messages);
+ EditableCheckBoxModel history = new EditableCheckBoxModel(getString(R.string.page_name_history));
+ history.setChecked(getVisibility(R.string.key_page_history_visibility))
+ .setInputText(String.valueOf(getPosition(R.string.key_page_history_position, 4)));
+ models.add(history);
+ EditableCheckBoxModel search = new EditableCheckBoxModel(getString(R.string.page_name_search));
+ search.setChecked(getVisibility(R.string.key_page_search_visibility))
+ .setInputText(String.valueOf(getPosition(R.string.key_page_search_position, 5)));
+ models.add(search);
+ EditableCheckBoxModel list = new EditableCheckBoxModel(getString(R.string.page_name_list));
+ list.setChecked(getVisibility(R.string.key_page_list_visibility))
+ .setInputText(String.valueOf(getPosition(R.string.key_page_list_position, 6)));
+ models.add(list);
+ return models.toArray(new EditableCheckBoxModel[models.size()]);
+ }
+
+ private ListView getListView()
+ {
+ return (ListView) findViewById(R.id.listview_edit_list);
+ }
+
+ private MainActivity getMainActivity()
+ {
+ return (MainActivity) getParent();
+ }
+
+ private UserPreferenceHelper getPreference()
+ {
+ return new UserPreferenceHelper(this);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ UserPreferenceHelper userPreferenceHelper = getPreference();
+ setTheme(Themes.getTheme(((Application) getApplication()).getThemeIndex()));
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.layout_edit_list);
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ initializeViews();
+ Logger.debug("EditTabActivity:onCreate");
+ }
+
+ @Override
+ protected void onDestroy()
+ {
+ EditableCheckBoxModel messages = (EditableCheckBoxModel) adapter.getItem(3);
+ putVisibility(R.string.key_page_messages_visibility, messages.isChecked());
+ //TODO putPosition(R.string.key_page_messages_position, Integer.parseInt(messages.getInputText()));
+ EditableCheckBoxModel history = (EditableCheckBoxModel) adapter.getItem(4);
+ putVisibility(R.string.key_page_history_visibility, history.isChecked());
+ EditableCheckBoxModel search = (EditableCheckBoxModel) adapter.getItem(5);
+ putVisibility(R.string.key_page_search_visibility, search.isChecked());
+ EditableCheckBoxModel list = (EditableCheckBoxModel) adapter.getItem(6);
+ putVisibility(R.string.key_page_list_visibility, list.isChecked());
+ new Notificator(this, R.string.notice_tab_editted).makeToast().show();
+ super.onDestroy();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case android.R.id.home:
+ {
+ NavUtils.navigateUpFromSameTask(this);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ private int getPosition(int key, int defaultValue)
+ {
+ return Integer.parseInt(getPreference().getValue(key, String.valueOf(defaultValue)));
+ }
+
+ private boolean getVisibility(int key)
+ {
+ return getPreference().getValue(key, true);
+ }
+
+ private void initializeViews()
+ {
+ ListView listView = getListView();
+ adapter = new CustomListAdapter<>(this, EditableCheckBoxModel.class);
+ listView.setAdapter(adapter);
+ adapter.addToTop(getCheckBoxItems());
+ adapter.update();
+ }
+
+ private void putPosition(int key, int value)
+ {
+ getPreference().putValue(key, String.valueOf(value));
+ }
+
+ private void putVisibility(int key, boolean value)
+ {
+ getPreference().putValue(key, value);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditTemplateActivity.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditTemplateActivity.java
new file mode 100644
index 00000000..51673575
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/EditTemplateActivity.java
@@ -0,0 +1,245 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.activity;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.NavUtils;
+import android.text.TextUtils;
+import android.util.SparseBooleanArray;
+import android.view.*;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import net.lacolaco.smileessence.Application;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.entity.Template;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.util.Themes;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.EditTextDialogFragment;
+
+import java.util.List;
+
+public class EditTemplateActivity extends Activity implements AdapterView.OnItemClickListener,
+ AbsListView.MultiChoiceModeListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private CustomListAdapter<Template> adapter;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private ListView getListView()
+ {
+ return (ListView) findViewById(R.id.listview_edit_list);
+ }
+
+ private Template[] getTemplates()
+ {
+ List<Template> all = Template.getAll();
+ return all.toArray(new Template[all.size()]);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface Callback ---------------------
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu)
+ {
+ menu.clear();
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.edit_list, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu)
+ {
+ return false;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case R.id.menu_edit_list_delete:
+ {
+ deleteSelectedItems();
+ }
+ }
+ mode.finish();
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode)
+ {
+ }
+
+ // --------------------- Interface MultiChoiceModeListener ---------------------
+
+ @Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked)
+ {
+ }
+
+ // --------------------- Interface OnItemClickListener ---------------------
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id)
+ {
+ openEditTemplateDialog(position);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ setTheme(Themes.getTheme(((Application) getApplication()).getThemeIndex()));
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.layout_edit_list);
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ initializeViews();
+ Logger.debug("EditTemplateActivity:onCreate");
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ MenuItem add = menu.add(Menu.NONE, R.id.menu_edit_list_add, Menu.NONE, "");
+ add.setIcon(android.R.drawable.ic_menu_add);
+ add.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case R.id.menu_edit_list_add:
+ {
+ addNewTemplate();
+ break;
+ }
+ case android.R.id.home:
+ {
+ NavUtils.navigateUpFromSameTask(this);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void deleteSelectedItems()
+ {
+ SparseBooleanArray checkedItems = getListView().getCheckedItemPositions();
+ adapter.setNotifiable(false);
+ for(int i = adapter.getCount() - 1; i > -1; i--)
+ {
+ if(checkedItems.get(i))
+ {
+ Template template = adapter.removeItem(i);
+ template.delete();
+ }
+ }
+ adapter.setNotifiable(true);
+ adapter.notifyDataSetChanged();
+ updateListView();
+ }
+
+ public void openEditTemplateDialog(int position)
+ {
+ final Template template = (Template) adapter.getItem(position);
+ EditTextDialogFragment dialogFragment = new EditTextDialogFragment()
+ {
+ @Override
+ public void onTextInput(String text)
+ {
+ if(TextUtils.isEmpty(text.trim()))
+ {
+ return;
+ }
+ template.text = text;
+ template.save();
+ adapter.notifyDataSetChanged();
+ updateListView();
+ }
+ };
+ dialogFragment.setParams(getString(R.string.dialog_title_edit), template.text);
+ DialogHelper.showDialog(this, dialogFragment);
+ }
+
+ private void addNewTemplate()
+ {
+ final Template template = new Template();
+ EditTextDialogFragment dialogFragment = new EditTextDialogFragment()
+ {
+ @Override
+ public void onTextInput(String text)
+ {
+ if(TextUtils.isEmpty(text.trim()))
+ {
+ return;
+ }
+ template.text = text;
+ template.save();
+ adapter.addToBottom(template);
+ adapter.notifyDataSetChanged();
+ updateListView();
+ }
+ };
+ dialogFragment.setParams(getString(R.string.dialog_title_add), "");
+ DialogHelper.showDialog(this, dialogFragment);
+ }
+
+ private void initializeViews()
+ {
+ ListView listView = getListView();
+ adapter = new CustomListAdapter<>(this, Template.class);
+ listView.setAdapter(adapter);
+ adapter.addToTop(getTemplates());
+ adapter.update();
+ listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ listView.setOnItemClickListener(this);
+ listView.setMultiChoiceModeListener(this);
+ }
+
+ private void updateListView()
+ {
+ getListView().requestLayout();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/LicenseActivity.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/LicenseActivity.java
new file mode 100644
index 00000000..470aac03
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/LicenseActivity.java
@@ -0,0 +1,104 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.activity;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.NavUtils;
+import android.view.MenuItem;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import net.lacolaco.smileessence.Application;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.util.Themes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LicenseActivity extends Activity
+{
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private List<String> getFileNames()
+ {
+ List<String> apacheFiles = new ArrayList<>();
+ apacheFiles.add(getString(R.string.library_name_twitter4j));
+ apacheFiles.add(getString(R.string.library_name_crouton));
+ apacheFiles.add(getString(R.string.library_name_pull_to_refresh));
+ apacheFiles.add(getString(R.string.library_name_volley));
+ apacheFiles.add(getString(R.string.library_name_activeandroid));
+ apacheFiles.add(getString(R.string.library_name_guava));
+ apacheFiles.add(getString(R.string.library_name_twitter_text));
+ return apacheFiles;
+ }
+
+ private String getMarkerString()
+ {
+ return "-";
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ setTheme(Themes.getTheme(((Application) getApplication()).getThemeIndex()));
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.layout_license);
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+
+ setFiles();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case android.R.id.home:
+ {
+ NavUtils.navigateUpFromSameTask(this);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ private void setFiles()
+ {
+ LinearLayout files = (LinearLayout) findViewById(R.id.linear_license_files);
+ List<String> apacheFiles = getFileNames();
+ String marker = getMarkerString();
+ for(String apacheFile : apacheFiles)
+ {
+ TextView name = new TextView(this);
+ name.setText(String.format("%s %s", marker, apacheFile));
+ files.addView(name);
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/MainActivity.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/MainActivity.java
new file mode 100644
index 00000000..427973f0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/MainActivity.java
@@ -0,0 +1,893 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.activity;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.support.v4.view.ViewPager;
+import android.text.TextUtils;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.WindowManager;
+import android.widget.ImageView;
+import net.lacolaco.smileessence.Application;
+import net.lacolaco.smileessence.IntentRouter;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.CommandSettingCache;
+import net.lacolaco.smileessence.data.UserListCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.entity.CommandSetting;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.preference.AppPreferenceHelper;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.twitter.OAuthSession;
+import net.lacolaco.smileessence.twitter.StatusFilter;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.UserStreamListener;
+import net.lacolaco.smileessence.twitter.task.*;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.*;
+import net.lacolaco.smileessence.view.*;
+import net.lacolaco.smileessence.view.adapter.*;
+import net.lacolaco.smileessence.view.dialog.ConfirmDialogFragment;
+import net.lacolaco.smileessence.viewmodel.MessageViewModel;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import net.lacolaco.smileessence.viewmodel.UserListListAdapter;
+import net.lacolaco.smileessence.viewmodel.menu.MainActivityMenuHelper;
+import twitter4j.*;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+public class MainActivity extends Activity
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final int REQUEST_OAUTH = 10;
+ public static final int REQUEST_GET_PICTURE_FROM_GALLERY = 11;
+ public static final int REQUEST_GET_PICTURE_FROM_CAMERA = 12;
+ public static final int PAGE_GONE = -1;
+ public static final int PAGE_POST = 0;
+ public static final int ADAPTER_HOME = 1;
+ public static final int ADAPTER_MENTIONS = 2;
+ public static final int ADAPTER_MESSAGES = 3;
+ public static final int ADAPTER_HISTORY = 4;
+ public static final int ADAPTER_SEARCH = 5;
+ public static final int ADAPTER_USERLIST = 6;
+ private static final String KEY_LAST_USED_SEARCH_QUERY = "lastUsedSearchQuery";
+ private static final String KEY_LAST_USED_ACCOUNT_ID = "lastUsedAccountID";
+ private static final String KEY_LAST_USER_LIST = "lastUsedUserList";
+ private int pageIndexMessages;
+ private int pageIndexHistory;
+ private int pageIndexSearch;
+ private int pageIndexUserlist;
+ private ViewPager viewPager;
+ private PageListAdapter pagerAdapter;
+ private OAuthSession oauthSession;
+ private Account currentAccount;
+ private TwitterStream stream;
+ private HashMap<Integer, CustomListAdapter<?>> adapterMap = new HashMap<>();
+ private boolean streaming = false;
+ private Uri cameraTempFilePath;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public AppPreferenceHelper getAppPreferenceHelper()
+ {
+ return new AppPreferenceHelper(this);
+ }
+
+ public Uri getCameraTempFilePath()
+ {
+ return cameraTempFilePath;
+ }
+
+ public void setCameraTempFilePath(Uri cameraTempFilePath)
+ {
+ this.cameraTempFilePath = cameraTempFilePath;
+ }
+
+ public Account getCurrentAccount()
+ {
+ return currentAccount;
+ }
+
+ public void setCurrentAccount(Account account)
+ {
+ this.currentAccount = account;
+ }
+
+ private String getLastSearch()
+ {
+ return getAppPreferenceHelper().getValue(KEY_LAST_USED_SEARCH_QUERY, "");
+ }
+
+ public void setLastSearch(String query)
+ {
+ getAppPreferenceHelper().putValue(KEY_LAST_USED_SEARCH_QUERY, query);
+ }
+
+ private long getLastUsedAccountID()
+ {
+ String id = getAppPreferenceHelper().getValue(KEY_LAST_USED_ACCOUNT_ID, "");
+ if(TextUtils.isEmpty(id))
+ {
+ return PAGE_GONE;
+ }
+ else
+ {
+ return Long.parseLong(id);
+ }
+ }
+
+ private void setLastUsedAccountID(Account account)
+ {
+ getAppPreferenceHelper().putValue(KEY_LAST_USED_ACCOUNT_ID, account.getId());
+ }
+
+ private String getLastUserList()
+ {
+ return getAppPreferenceHelper().getValue(KEY_LAST_USER_LIST, "");
+ }
+
+ public Collection<CustomListAdapter<?>> getListAdapters()
+ {
+ return adapterMap.values();
+ }
+
+ public int getPageHome()
+ {
+ return ADAPTER_HOME;
+ }
+
+ public int getPageIndexHistory()
+ {
+ return pageIndexHistory;
+ }
+
+ public int getPageIndexMessages()
+ {
+ return pageIndexMessages;
+ }
+
+ public int getPageIndexSearch()
+ {
+ return pageIndexSearch;
+ }
+
+ public int getPageIndexUserlist()
+ {
+ return pageIndexUserlist;
+ }
+
+ public int getPageMentions()
+ {
+ return ADAPTER_MENTIONS;
+ }
+
+ public int getPagePost()
+ {
+ return PAGE_POST;
+ }
+
+ public PageListAdapter getPagerAdapter()
+ {
+ return pagerAdapter;
+ }
+
+ public int getThemeIndex()
+ {
+ return ((Application) getApplication()).getThemeIndex();
+ }
+
+ public UserPreferenceHelper getUserPreferenceHelper()
+ {
+ return new UserPreferenceHelper(this);
+ }
+
+ public String getVersion()
+ {
+ return getString(R.string.app_version);
+ }
+
+ private boolean isAuthorized()
+ {
+ long lastUsedAccountID = getLastUsedAccountID();
+ return lastUsedAccountID >= 0 && Account.load(Account.class, lastUsedAccountID) != null;
+ }
+
+ /**
+ * Returns which twitter stream is running
+ *
+ * @return
+ */
+ public boolean isStreaming()
+ {
+ return streaming;
+ }
+
+ public void setStreaming(boolean streaming)
+ {
+ this.streaming = streaming;
+ }
+
+ public void setSelectedPageIndex(int position)
+ {
+ viewPager.setCurrentItem(position, true);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface Callback ---------------------
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event)
+ {
+ if(event.getAction() != KeyEvent.ACTION_DOWN)
+ {
+ return super.dispatchKeyEvent(event);
+ }
+ switch(event.getKeyCode())
+ {
+ case KeyEvent.KEYCODE_BACK:
+ {
+ finish();
+ return false;
+ }
+ default:
+ {
+ return super.dispatchKeyEvent(event);
+ }
+ }
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void finish()
+ {
+ if(viewPager == null)
+ {
+ forceFinish();
+ }
+ else if(viewPager.getCurrentItem() != ADAPTER_HOME)
+ {
+ viewPager.setCurrentItem(ADAPTER_HOME, true);
+ }
+ else
+ {
+ ConfirmDialogFragment.show(this, getString(R.string.dialog_confirm_finish_app), new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ forceFinish();
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data)
+ {
+ switch(requestCode)
+ {
+ case REQUEST_OAUTH:
+ {
+ receiveOAuth(requestCode, resultCode, data);
+ break;
+ }
+ case REQUEST_GET_PICTURE_FROM_GALLERY:
+ case REQUEST_GET_PICTURE_FROM_CAMERA:
+ {
+ getImageUri(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ setTheme();
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ if(isAuthorized())
+ {
+ setupAccount();
+ startMainLogic();
+ IntentRouter.onNewIntent(this, getIntent());
+ }
+ else
+ {
+ startOAuthActivity();
+ }
+ Logger.debug("MainActivity:onCreate");
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu)
+ {
+ MainActivityMenuHelper.addItemsToMenu(this, menu);
+ return true;
+ }
+
+ @Override
+ protected void onDestroy()
+ {
+ super.onDestroy();
+ if(stream != null)
+ {
+ stream.shutdown();
+ }
+ Logger.debug("MainActivity:onDestroy");
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent)
+ {
+ IntentRouter.onNewIntent(this, intent);
+ super.onNewIntent(intent);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ return MainActivityMenuHelper.onItemSelected(this, item);
+ }
+
+ @Override
+ protected void onPause()
+ {
+ super.onPause();
+ Logger.debug("MainActivity:onPause");
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ Notificator.stopNotification();
+ }
+
+ @Override
+ protected void onResume()
+ {
+ super.onResume();
+ Logger.debug("MainActivity:onResume");
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ Notificator.startNotification();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public int addListPage(String name, Class<? extends CustomListFragment> fragmentClass, CustomListAdapter<?> adapter, int adapterIndex, boolean visible)
+ {
+ if(visible)
+ {
+ Bundle args = new Bundle();
+ args.putInt(CustomListFragment.ADAPTER_INDEX, adapterIndex);
+ addPage(name, fragmentClass, args, false);
+ adapterMap.put(adapterIndex, adapter);
+ return pagerAdapter.getCount() - 1;
+ }
+ else
+ {
+ adapterMap.put(adapterIndex, adapter);
+ return PAGE_GONE;
+ }
+ }
+
+ public boolean addPage(String name, Class<? extends Fragment> fragmentClass, Bundle args, boolean withNotify)
+ {
+ if(withNotify)
+ {
+ return this.pagerAdapter.addPage(name, fragmentClass, args);
+ }
+ else
+ {
+ return this.pagerAdapter.addPageWithoutNotify(name, fragmentClass, args);
+ }
+ }
+
+ public void forceFinish()
+ {
+ super.finish();
+ }
+
+ public CustomListAdapter<?> getListAdapter(int i)
+ {
+ return adapterMap.get(i);
+ }
+
+ public void openPostPage()
+ {
+ setSelectedPageIndex(MainActivity.PAGE_POST);
+ }
+
+ public void openPostPageWithImage(Uri uri)
+ {
+ try
+ {
+ Cursor c = getContentResolver().query(uri, null, null, null, null);
+ c.moveToFirst();
+ String path = c.getString(c.getColumnIndex(MediaStore.MediaColumns.DATA));
+ String rotatedPath = BitmapOptimizer.rotateImageByExif(this, path);
+ PostState.getState().beginTransaction()
+ .setMediaFilePath(rotatedPath)
+ .commitWithOpen(this);
+ Notificator.publish(this, R.string.notice_select_image_succeeded);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ Notificator.publish(this, R.string.notice_select_image_failed, NotificationType.ALERT);
+ }
+ }
+
+ /**
+ * Open search page
+ */
+ public void openSearchPage()
+ {
+ setSelectedPageIndex(pageIndexSearch);
+ }
+
+ /**
+ * Open search page with given query
+ */
+ public void openSearchPage(final String query)
+ {
+ startNewSearch(TwitterApi.getTwitter(getCurrentAccount()), query);
+ openSearchPage();
+ }
+
+ public void openUserListPage(String listFullName)
+ {
+ startUserList(TwitterApi.getTwitter(getCurrentAccount()), listFullName);
+ openUserListPage();
+ }
+
+ public void saveLastUserList(String lastUserList)
+ {
+ getAppPreferenceHelper().putValue(KEY_LAST_USER_LIST, lastUserList);
+ }
+
+ public void setListAdapter(int adapterIndex, CustomListAdapter<?> adapter)
+ {
+ adapterMap.put(adapterIndex, adapter);
+ }
+
+ public void setSelectedPageIndex(final int position, final boolean smooth)
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ viewPager.setCurrentItem(position, smooth);
+ }
+ }.post();
+ }
+
+ public void startMainLogic()
+ {
+ initializeView();
+ initCommandSetting();
+ startTwitter();
+ }
+
+ public void startNewSearch(final Twitter twitter, final String query)
+ {
+ setLastSearch(query);
+ if(!TextUtils.isEmpty(query))
+ {
+ final SearchListAdapter adapter = (SearchListAdapter) getListAdapter(ADAPTER_SEARCH);
+ adapter.initSearch(query);
+ adapter.clear();
+ adapter.updateForce();
+ new SearchTask(twitter, query, this)
+ {
+ @Override
+ protected void onPostExecute(QueryResult queryResult)
+ {
+ super.onPostExecute(queryResult);
+ if(queryResult != null)
+ {
+ List<twitter4j.Status> tweets = queryResult.getTweets();
+ for(int i = tweets.size() - 1; i >= 0; i--)
+ {
+ twitter4j.Status status = tweets.get(i);
+ if(!status.isRetweet())
+ {
+ StatusViewModel viewModel = new StatusViewModel(status, getCurrentAccount());
+ adapter.addToTop(viewModel);
+ StatusFilter.filter(MainActivity.this, viewModel);
+ }
+ }
+ adapter.setTopID(queryResult.getMaxId());
+ adapter.updateForce();
+ }
+ }
+ }.execute();
+ }
+ }
+
+ public boolean startStream()
+ {
+ if(!new NetworkHelper(this).canConnect())
+ {
+ return false;
+ }
+ if(stream != null)
+ {
+ stream.shutdown();
+ }
+ stream = new TwitterApi(currentAccount).getTwitterStream();
+ UserStreamListener listener = new UserStreamListener(this);
+ stream.addListener(listener);
+ stream.addConnectionLifeCycleListener(listener);
+ stream.user();
+ return true;
+ }
+
+ public boolean startTwitter()
+ {
+ if(!startStream())
+ {
+ return false;
+ }
+ int count = TwitterUtils.getPagingCount(this);
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ Paging paging = TwitterUtils.getPaging(count);
+ initInvisibleUser(twitter);
+ initUserListCache(twitter);
+ initHome(twitter, paging);
+ initMentions(twitter, paging);
+ initMessages(twitter, paging);
+ initSearch(twitter);
+ initUserList(twitter);
+ updateActionBarIcon();
+ return true;
+ }
+
+ public void updateActionBarIcon()
+ {
+ Twitter twitter = new TwitterApi(currentAccount).getTwitter();
+ final ImageView homeIcon = (ImageView) findViewById(android.R.id.home);
+ ShowUserTask userTask = new ShowUserTask(twitter, currentAccount.userID)
+ {
+ @Override
+ protected void onPostExecute(User user)
+ {
+ super.onPostExecute(user);
+ if(user != null)
+ {
+ String urlHttps = user.getProfileImageURLHttps();
+ homeIcon.setScaleType(ImageView.ScaleType.FIT_CENTER);
+ new BitmapURLTask(urlHttps, homeIcon).execute();
+ }
+ }
+ };
+ userTask.execute();
+ }
+
+ private void addHistoryPage()
+ {
+ boolean visible = getUserPreferenceHelper().getValue(R.string.key_page_history_visibility, true);
+ getUserPreferenceHelper().putValue(R.string.key_page_history_visibility, visible);
+ EventListAdapter historyAdapter = new EventListAdapter(this);
+ pageIndexHistory = addListPage(getString(R.string.page_name_history), HistoryFragment.class, historyAdapter, ADAPTER_HISTORY, visible);
+ }
+
+ private void addHomePage()
+ {
+ StatusListAdapter homeAdapter = new StatusListAdapter(this);
+ addListPage(getString(R.string.page_name_home), HomeFragment.class, homeAdapter, ADAPTER_HOME, true);
+ }
+
+ private void addMentionsPage()
+ {
+ StatusListAdapter mentionsAdapter = new StatusListAdapter(this);
+ addListPage(getString(R.string.page_name_mentions), MentionsFragment.class, mentionsAdapter, ADAPTER_MENTIONS, true);
+ }
+
+ private void addMessagesPage()
+ {
+ boolean visible = getUserPreferenceHelper().getValue(R.string.key_page_messages_visibility, true);
+ getUserPreferenceHelper().putValue(R.string.key_page_messages_visibility, visible);
+ MessageListAdapter messagesAdapter = new MessageListAdapter(this);
+ pageIndexMessages = addListPage(getString(R.string.page_name_messages), MessagesFragment.class, messagesAdapter, ADAPTER_MESSAGES, visible);
+ }
+
+ private void addPostPage()
+ {
+ addPage(getString(R.string.page_name_post), PostFragment.class, null, true);
+ }
+
+ private void addSearchPage()
+ {
+ boolean visible = getUserPreferenceHelper().getValue(R.string.key_page_search_visibility, true);
+ getUserPreferenceHelper().putValue(R.string.key_page_search_visibility, visible);
+ SearchListAdapter searchAdapter = new SearchListAdapter(this);
+ pageIndexSearch = addListPage(getString(R.string.page_name_search), SearchFragment.class, searchAdapter, ADAPTER_SEARCH, visible);
+ }
+
+ private void addUserListPage()
+ {
+ boolean visible = getUserPreferenceHelper().getValue(R.string.key_page_list_visibility, true);
+ getUserPreferenceHelper().putValue(R.string.key_page_list_visibility, visible);
+ UserListListAdapter userListAdapter = new UserListListAdapter(this);
+ pageIndexUserlist = addListPage(getString(R.string.page_name_list), UserListFragment.class, userListAdapter, ADAPTER_USERLIST, visible);
+ }
+
+ private void getImageUri(int requestCode, int resultCode, Intent data)
+ {
+ if(resultCode != RESULT_OK)
+ {
+ Logger.error(requestCode);
+ Notificator.publish(this, R.string.notice_select_image_failed);
+ finish();
+ return;
+ }
+ Uri uri;
+ if(requestCode == REQUEST_GET_PICTURE_FROM_GALLERY)
+ {
+ uri = data.getData();
+ }
+ else
+ {
+ uri = getCameraTempFilePath();
+ }
+ openPostPageWithImage(uri);
+ }
+
+ private void initCommandSetting()
+ {
+ List<CommandSetting> commandSettings = CommandSetting.getAll();
+ for(CommandSetting setting : commandSettings)
+ {
+ CommandSettingCache.getInstance().put(setting);
+ }
+ }
+
+ private void initHome(final Twitter twitter, final Paging paging)
+ {
+ new HomeTimelineTask(twitter, this, paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ StatusListAdapter adapter = (StatusListAdapter) getListAdapter(ADAPTER_HOME);
+ for(twitter4j.Status status : statuses)
+ {
+ StatusViewModel statusViewModel = new StatusViewModel(status, currentAccount);
+ adapter.addToBottom(statusViewModel);
+ StatusFilter.filter(MainActivity.this, statusViewModel);
+ }
+ adapter.updateForce();
+ }
+ }.execute();
+ }
+
+ private void initInvisibleUser(Twitter twitter)
+ {
+ new BlockIDsTask(twitter).execute();
+ new MutesIDsTask(twitter).execute();
+ }
+
+ private void initMentions(final Twitter twitter, final Paging paging)
+ {
+ new MentionsTimelineTask(twitter, this, paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ StatusListAdapter adapter = (StatusListAdapter) getListAdapter(ADAPTER_MENTIONS);
+ for(twitter4j.Status status : statuses)
+ {
+ adapter.addToBottom(new StatusViewModel(status, currentAccount));
+ }
+ adapter.updateForce();
+ }
+ }.execute();
+ }
+
+ private void initMessages(final Twitter twitter, final Paging paging)
+ {
+ if(pageIndexMessages == PAGE_GONE)
+ {
+ return;
+ }
+ new DirectMessagesTask(twitter, this, paging)
+ {
+ @Override
+ protected void onPostExecute(DirectMessage[] directMessages)
+ {
+ super.onPostExecute(directMessages);
+ MessageListAdapter adapter = (MessageListAdapter) getListAdapter(ADAPTER_MESSAGES);
+ for(DirectMessage message : directMessages)
+ {
+ adapter.addToBottom(new MessageViewModel(message, currentAccount));
+ }
+ adapter.notifyDataSetChanged();
+ }
+ }.execute();
+ new SentDirectMessagesTask(twitter, this, paging)
+ {
+ @Override
+ protected void onPostExecute(DirectMessage[] directMessages)
+ {
+ super.onPostExecute(directMessages);
+ MessageListAdapter adapter = (MessageListAdapter) getListAdapter(ADAPTER_MESSAGES);
+ for(DirectMessage message : directMessages)
+ {
+ adapter.addToBottom(new MessageViewModel(message, currentAccount));
+ }
+ adapter.notifyDataSetChanged();
+ }
+ }.execute();
+ }
+
+ private void initPostState()
+ {
+ PostState.newState().beginTransaction().commit();
+ }
+
+ private void initSearch(Twitter twitter)
+ {
+ if(pageIndexSearch == PAGE_GONE)
+ {
+ return;
+ }
+ String lastUsedSearchQuery = getLastSearch();
+ if(!TextUtils.isEmpty(lastUsedSearchQuery))
+ {
+ startNewSearch(twitter, lastUsedSearchQuery);
+ }
+ }
+
+ private void initUserList(Twitter twitter)
+ {
+ if(pageIndexUserlist == PAGE_GONE)
+ {
+ return;
+ }
+ String lastUserList = getLastUserList();
+ if(!TextUtils.isEmpty(lastUserList))
+ {
+ startUserList(twitter, lastUserList);
+ }
+ }
+
+ private void initUserListCache(Twitter twitter)
+ {
+ UserListCache.getInstance().clear();
+ new GetUserListsTask(twitter).execute();
+ }
+
+ private void initializePages()
+ {
+ addPostPage();
+ addHomePage();
+ addMentionsPage();
+ addMessagesPage();
+ addHistoryPage();
+ addSearchPage();
+ addUserListPage();
+ pagerAdapter.refreshListNavigation();
+ viewPager.setOffscreenPageLimit(pagerAdapter.getCount());
+ initPostState();
+ setSelectedPageIndex(ADAPTER_HOME, false);
+ }
+
+ private void initializeView()
+ {
+ ActionBar bar = getActionBar();
+ bar.setDisplayShowHomeEnabled(true);
+ bar.setDisplayShowTitleEnabled(false);
+ bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
+ viewPager = (ViewPager) findViewById(R.id.viewPager);
+ pagerAdapter = new PageListAdapter(this, viewPager);
+ initializePages();
+ }
+
+ private void openUserListPage()
+ {
+ setSelectedPageIndex(pageIndexUserlist);
+ }
+
+ private void receiveOAuth(int requestCode, int resultCode, Intent data)
+ {
+ if(resultCode != RESULT_OK)
+ {
+ Logger.error(requestCode);
+ Notificator.publish(this, R.string.notice_error_authenticate);
+ finish();
+ }
+ else
+ {
+ Account account = new Account(data.getStringExtra(OAuthSession.KEY_TOKEN),
+ data.getStringExtra(OAuthSession.KEY_TOKEN_SECRET),
+ data.getLongExtra(OAuthSession.KEY_USER_ID, -1L),
+ data.getStringExtra(OAuthSession.KEY_SCREEN_NAME));
+ account.save();
+ setCurrentAccount(account);
+ setLastUsedAccountID(account);
+ startMainLogic();
+ }
+ }
+
+ private void setTheme()
+ {
+ ((Application) getApplication()).setThemeIndex(getUserPreferenceHelper().getValue(R.string.key_setting_theme, 0));
+ setTheme(Themes.getTheme(getThemeIndex()));
+ }
+
+ private void setupAccount()
+ {
+ Account account = Account.load(Account.class, getLastUsedAccountID());
+ setCurrentAccount(account);
+ }
+
+ private void startOAuthActivity()
+ {
+ startActivityForResult(new Intent(this, OAuthActivity.class), REQUEST_OAUTH);
+ }
+
+ private void startUserList(Twitter twitter, String listFullName)
+ {
+ saveLastUserList(listFullName);
+ final UserListListAdapter adapter = (UserListListAdapter) getListAdapter(ADAPTER_USERLIST);
+ adapter.setListFullName(listFullName);
+ adapter.clear();
+ adapter.updateForce();
+ new UserListStatusesTask(twitter, listFullName, this)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(twitter4j.Status status : statuses)
+ {
+ StatusViewModel statusViewModel = new StatusViewModel(status, getCurrentAccount());
+ adapter.addToBottom(statusViewModel);
+ StatusFilter.filter(MainActivity.this, statusViewModel);
+ }
+ adapter.updateForce();
+ }
+ }.execute();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/OAuthActivity.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/OAuthActivity.java
new file mode 100644
index 00000000..c06f2a50
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/OAuthActivity.java
@@ -0,0 +1,126 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.activity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.twitter.OAuthSession;
+import twitter4j.auth.AccessToken;
+
+public class OAuthActivity extends Activity implements View.OnClickListener, TextWatcher
+{
+
+ public static final int PIN_CODE_LENGTH = 7;
+ private TextView linkTextView;
+ private EditText pinEditText;
+ private Button authButton;
+ private OAuthSession oauthSession;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.layout_oauth);
+
+ linkTextView = (TextView) findViewById(R.id.textView_oauth_link);
+ pinEditText = (EditText) findViewById(R.id.editText_oauth_pin);
+ pinEditText.addTextChangedListener(this);
+ authButton = (Button) findViewById(R.id.button_oauth_auth);
+ authButton.setOnClickListener(this);
+ authButton.setEnabled(false);
+
+ oauthSession = new OAuthSession();
+ String url = oauthSession.getAuthorizationURL();
+ if(!TextUtils.isEmpty(url))
+ {
+ linkTextView.setText(url);
+ }
+ else
+ {
+ new Notificator(this, R.string.notice_error_authenticate_request).makeToast().show();
+ finish();
+ }
+ }
+
+ @Override
+ protected void onResume()
+ {
+ super.onResume();
+
+ }
+
+ @Override
+ public void onClick(View v)
+ {
+ switch(v.getId())
+ {
+ case R.id.button_oauth_auth:
+ {
+ AccessToken accessToken = oauthSession.getAccessToken(pinEditText.getText().toString());
+ if(accessToken != null)
+ {
+ Intent intent = new Intent();
+ intent.putExtra(OAuthSession.KEY_TOKEN, accessToken.getToken());
+ intent.putExtra(OAuthSession.KEY_TOKEN_SECRET, accessToken.getTokenSecret());
+ intent.putExtra(OAuthSession.KEY_USER_ID, accessToken.getUserId());
+ intent.putExtra(OAuthSession.KEY_SCREEN_NAME, accessToken.getScreenName());
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+ else
+ {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after)
+ {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count)
+ {
+ authButton.setEnabled(s.length() == PIN_CODE_LENGTH);
+ }
+
+ @Override
+ public void afterTextChanged(Editable s)
+ {
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/SettingActivity.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/SettingActivity.java
new file mode 100644
index 00000000..160417fc
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/activity/SettingActivity.java
@@ -0,0 +1,64 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.activity;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.NavUtils;
+import android.view.MenuItem;
+import net.lacolaco.smileessence.Application;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.util.Themes;
+
+public class SettingActivity extends Activity
+{
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ setTheme(Themes.getTheme(((Application) getApplication()).getThemeIndex()));
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.setting);
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case android.R.id.home:
+ {
+ NavUtils.navigateUpFromSameTask(this);
+ return true;
+ }
+ }
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/Command.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/Command.java
new file mode 100644
index 00000000..5985dcf0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/Command.java
@@ -0,0 +1,180 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.message.MessageCommandClipboard;
+import net.lacolaco.smileessence.command.message.MessageCommandSearchOnGoogle;
+import net.lacolaco.smileessence.command.message.MessageCommandShare;
+import net.lacolaco.smileessence.command.message.MessageCommandTofuBuster;
+import net.lacolaco.smileessence.command.status.*;
+import net.lacolaco.smileessence.command.user.*;
+import net.lacolaco.smileessence.data.CommandSettingCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.viewmodel.IViewModel;
+import twitter4j.DirectMessage;
+import twitter4j.Status;
+import twitter4j.User;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public abstract class Command implements IViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final int key;
+ private final Activity activity;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public Command(int key, Activity activity)
+ {
+ this.key = key;
+ this.activity = activity;
+ }
+
+ public static List<Command> getAllCommands(Activity activity)
+ {
+ List<Command> commands = new ArrayList<>();
+ commands.addAll(getStatusCommands(activity, null, null));
+ commands.addAll(getUserCommands(activity, null, null));
+ return commands;
+ }
+
+ public static List<Command> getUserCommands(Activity activity, User user, Account account)
+ {
+ List<Command> commands = new ArrayList<>();
+ commands.add(new UserCommandReply(activity, user));
+ commands.add(new UserCommandAddToReply(activity, user));
+ commands.add(new UserCommandSendMessage(activity, user, account));
+ commands.add(new UserCommandBlock(activity, user, account));
+ commands.add(new UserCommandUnblock(activity, user, account));
+ commands.add(new UserCommandReportForSpam(activity, user, account));
+ commands.add(new UserCommandOpenFavstar(activity, user));
+ commands.add(new UserCommandOpenAclog(activity, user));
+ commands.add(new UserCommandOpenTwilog(activity, user));
+ commands.add(new UserCommandIntroduce(activity, user));
+ return commands;
+ }
+
+ public static List<Command> getStatusCommands(Activity activity, Status status, Account account)
+ {
+ List<Command> commands = new ArrayList<>();
+ commands.add(new StatusCommandAddToReply(activity, status));
+ commands.add(new StatusCommandReplyToAll(activity, status, account));
+ commands.add(new StatusCommandOpenTalkView(activity, status, account));
+ commands.add(new StatusCommandFavAndRT(activity, status, account));
+ commands.add(new StatusCommandOpenQuoteDialog(activity, status));
+ commands.add(new StatusCommandShare(activity, status));
+ commands.add(new StatusCommandOpenInBrowser(activity, status));
+ commands.add(new StatusCommandClipboard(activity, status));
+ commands.add(new StatusCommandCopy(activity, status));
+ commands.add(new StatusCommandSearchOnGoogle(activity, status));
+ commands.add(new StatusCommandTofuBuster(activity, status));
+ commands.add(new StatusCommandNanigaja(activity, status, account));
+ commands.add(new StatusCommandMakeAnonymous(activity, status, account));
+ commands.add(new StatusCommandCongratulate(activity, status, account));
+ commands.add(new StatusCommandReview(activity, status));
+ commands.add(new StatusCommandAddToIgnore(activity, status));
+ return commands;
+ }
+
+ public static List<Command> getMessageCommands(Activity activity, DirectMessage message, Account account)
+ {
+ List<Command> commands = new ArrayList<>();
+ commands.add(new MessageCommandShare(activity, message));
+ commands.add(new MessageCommandClipboard(activity, message));
+ commands.add(new MessageCommandSearchOnGoogle(activity, message));
+ commands.add(new MessageCommandTofuBuster(activity, message));
+ return commands;
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static void filter(List<Command> commands)
+ {
+ Iterator<Command> iterator = commands.iterator();
+ while(iterator.hasNext())
+ {
+ Command command = iterator.next();
+ if(!command.isEnabled())
+ {
+ iterator.remove();
+ }
+ else if(command.getKey() >= 0)
+ {
+ boolean visibility = CommandSettingCache.getInstance().get(command.getKey());
+ if(!visibility)
+ {
+ iterator.remove();
+ }
+ }
+ }
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public Activity getActivity()
+ {
+ return activity;
+ }
+
+ public int getKey()
+ {
+ return key;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface IViewModel ---------------------
+
+ @Override
+ public View getView(Activity activity, LayoutInflater inflater, View convertedView)
+ {
+ if(convertedView == null)
+ {
+ convertedView = inflater.inflate(R.layout.menu_item_simple_text, null);
+ }
+ TextView textView = (TextView) convertedView.findViewById(R.id.textView_menuItem_simple);
+ textView.setText(getText());
+ return convertedView;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public abstract boolean execute();
+
+ public abstract String getText();
+
+ public abstract boolean isEnabled();
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenHashtagDialog.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenHashtagDialog.java
new file mode 100644
index 00000000..8042ca96
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenHashtagDialog.java
@@ -0,0 +1,71 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.HashtagDialogFragment;
+import twitter4j.HashtagEntity;
+
+public class CommandOpenHashtagDialog extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final HashtagEntity hashtagEntity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandOpenHashtagDialog(Activity activity, HashtagEntity hashtagEntity)
+ {
+ super(-1, activity);
+ this.hashtagEntity = hashtagEntity;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return "#" + hashtagEntity.getText();
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ HashtagDialogFragment dialogFragment = new HashtagDialogFragment();
+ dialogFragment.setText(hashtagEntity.getText());
+ DialogHelper.showDialog(getActivity(), dialogFragment);
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenSearch.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenSearch.java
new file mode 100644
index 00000000..d6399d5b
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenSearch.java
@@ -0,0 +1,74 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.entity.SearchQuery;
+
+public class CommandOpenSearch extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final SearchQuery query;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandOpenSearch(Activity activity, SearchQuery searchQuery)
+ {
+ super(-1, activity);
+ this.query = searchQuery;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public SearchQuery getQuery()
+ {
+ return query;
+ }
+
+ @Override
+ public String getText()
+ {
+ return query.query;
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ return activity.getPageIndexSearch() != MainActivity.PAGE_GONE;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ ((MainActivity) getActivity()).openSearchPage(query.query);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenTemplateList.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenTemplateList.java
new file mode 100644
index 00000000..3aa954da
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenTemplateList.java
@@ -0,0 +1,66 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.entity.Template;
+import net.lacolaco.smileessence.view.dialog.ChooseTemplateDialogFragment;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+
+public class CommandOpenTemplateList extends Command
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandOpenTemplateList(Activity activity)
+ {
+ super(-1, activity);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_open_template_list);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return !Template.getAll().isEmpty();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ ChooseTemplateDialogFragment fragment = new ChooseTemplateDialogFragment();
+ DialogHelper.showDialog(getActivity(), fragment);
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenURL.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenURL.java
new file mode 100644
index 00000000..998596d8
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenURL.java
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import net.lacolaco.smileessence.util.IntentUtils;
+
+public class CommandOpenURL extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String url;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandOpenURL(Activity activity, String url)
+ {
+ super(-1, activity);
+ this.url = url;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return url;
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ IntentUtils.startActivityIfFound(getActivity(), intent);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenUserDetail.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenUserDetail.java
new file mode 100644
index 00000000..8bdd4231
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenUserDetail.java
@@ -0,0 +1,95 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.ShowUserTask;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment;
+import twitter4j.User;
+
+public class CommandOpenUserDetail extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String screenName;
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandOpenUserDetail(Activity activity, String screenName, Account account)
+ {
+ super(-1, activity);
+ this.screenName = screenName;
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return String.format("@%s", screenName);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ new ShowUserTask(new TwitterApi(account).getTwitter(), screenName)
+ {
+ @Override
+ protected void onPostExecute(User user)
+ {
+ super.onPostExecute(user);
+ if(user != null)
+ {
+ UserDetailDialogFragment fragment = new UserDetailDialogFragment();
+ fragment.setUserID(user.getId());
+ DialogHelper.showDialog(getActivity(), fragment);
+ }
+ else
+ {
+ Notificator.publish(getActivity(), R.string.notice_error_show_user, NotificationType.ALERT);
+ }
+ }
+ }.execute();
+
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenUserList.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenUserList.java
new file mode 100644
index 00000000..a722aaf0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandOpenUserList.java
@@ -0,0 +1,68 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.activity.MainActivity;
+
+public class CommandOpenUserList extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String listFullName;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandOpenUserList(Activity activity, String listFullName)
+ {
+ super(-1, activity);
+ this.listFullName = listFullName;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return listFullName;
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ activity.openUserListPage(listFullName);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandPasteToPost.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandPasteToPost.java
new file mode 100644
index 00000000..f4666055
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandPasteToPost.java
@@ -0,0 +1,71 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.view.adapter.PostState;
+
+public class CommandPasteToPost extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String text;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandPasteToPost(Activity activity, String text)
+ {
+ super(-1, activity);
+ this.text = text;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_paste_to_post);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ PostState.getState().beginTransaction()
+ .appendText(" " + text)
+ .commitWithOpen((MainActivity) getActivity());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandSaveAsTemplate.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandSaveAsTemplate.java
new file mode 100644
index 00000000..fe5cb393
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandSaveAsTemplate.java
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.entity.Template;
+import net.lacolaco.smileessence.notification.Notificator;
+
+public class CommandSaveAsTemplate extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String text;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandSaveAsTemplate(Activity activity, String text)
+ {
+ super(-1, activity);
+ this.text = text;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_save_as_template);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ new Template(text, 0).save();
+ new Notificator(getActivity(), R.string.notice_save_as_template).publish();
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandSearchOnTwitter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandSearchOnTwitter.java
new file mode 100644
index 00000000..f1557dd6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/CommandSearchOnTwitter.java
@@ -0,0 +1,68 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+
+public class CommandSearchOnTwitter extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String text;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CommandSearchOnTwitter(Activity activity, String text)
+ {
+ super(-1, activity);
+ this.text = text;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_search_on_twitter);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return ((MainActivity) getActivity()).getPageIndexSearch() != MainActivity.PAGE_GONE;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ ((MainActivity) getActivity()).openSearchPage(text);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/IConfirmable.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/IConfirmable.java
new file mode 100644
index 00000000..47c17e65
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/IConfirmable.java
@@ -0,0 +1,33 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command;
+
+/**
+ * Marker interface to make command confirmable
+ */
+public interface IConfirmable
+{
+
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommand.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommand.java
new file mode 100644
index 00000000..2fecb24f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommand.java
@@ -0,0 +1,52 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.message;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.command.Command;
+import twitter4j.DirectMessage;
+
+public abstract class MessageCommand extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final DirectMessage message;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MessageCommand(int key, Activity activity, DirectMessage message)
+ {
+ super(key, activity);
+ this.message = message;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ protected DirectMessage getMessage()
+ {
+ return message;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandClipboard.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandClipboard.java
new file mode 100644
index 00000000..07efa0bd
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandClipboard.java
@@ -0,0 +1,68 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.message;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.DirectMessage;
+
+public class MessageCommandClipboard extends MessageCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MessageCommandClipboard(Activity activity, DirectMessage message)
+ {
+ super(-1, activity, message);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_clipboard);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ ClipboardManager manager = (ClipboardManager) getActivity().getSystemService(Activity.CLIPBOARD_SERVICE);
+ manager.setPrimaryClip(ClipData.newPlainText("message text", getMessage().getText()));
+ Notificator.publish(getActivity(), R.string.notice_copy_clipboard);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandSearchOnGoogle.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandSearchOnGoogle.java
new file mode 100644
index 00000000..15f3ab38
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandSearchOnGoogle.java
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.message;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.SearchOnGoogleDialogFragment;
+import twitter4j.DirectMessage;
+
+public class MessageCommandSearchOnGoogle extends MessageCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MessageCommandSearchOnGoogle(Activity activity, DirectMessage message)
+ {
+ super(R.id.key_command_message_search_on_google, activity, message);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_search_on_google);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ SearchOnGoogleDialogFragment dialogFragment = new SearchOnGoogleDialogFragment();
+ dialogFragment.setText(getMessage().getText());
+ DialogHelper.showDialog(getActivity(), dialogFragment);
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandShare.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandShare.java
new file mode 100644
index 00000000..811e1d4e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandShare.java
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.message;
+
+import android.app.Activity;
+import android.content.Intent;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.IntentUtils;
+import twitter4j.DirectMessage;
+
+public class MessageCommandShare extends MessageCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MessageCommandShare(Activity activity, DirectMessage message)
+ {
+ super(R.id.key_command_message_share, activity, message);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_share);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_SEND);
+ intent.setType("text/plain");
+ intent.putExtra(Intent.EXTRA_TEXT, TwitterUtils.getMessageSummary(getMessage()));
+ IntentUtils.startActivityIfFound(getActivity(), intent);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandTofuBuster.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandTofuBuster.java
new file mode 100644
index 00000000..eedbad95
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/message/MessageCommandTofuBuster.java
@@ -0,0 +1,79 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.message;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.DirectMessage;
+
+public class MessageCommandTofuBuster extends MessageCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MessageCommandTofuBuster(Activity activity, DirectMessage message)
+ {
+ super(R.id.key_command_message_tofubuster, activity, message);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_tofubuster);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ String ACTION_SHOW_TEXT = "com.product.kanzmrsw.tofubuster.ACTION_SHOW_TEXT";
+ String text = getMessage().getText();
+ Intent i = new Intent(ACTION_SHOW_TEXT);
+ i.putExtra(Intent.EXTRA_TEXT, text);
+ i.putExtra(Intent.EXTRA_SUBJECT, getActivity().getString(R.string.app_name));
+ i.putExtra("isCopyEnabled", true);
+ try
+ {
+ getActivity().startActivity(i);
+ }
+ catch(ActivityNotFoundException e)
+ {
+ new Notificator(getActivity(), R.string.notice_tofubuster_not_found).publish();
+ }
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommand.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommand.java
new file mode 100644
index 00000000..f4a7c6e6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommand.java
@@ -0,0 +1,72 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.post;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.view.adapter.PostState;
+
+public abstract class PostCommand extends Command
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public PostCommand(Activity activity)
+ {
+ super(-1, activity);
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public abstract String build(String s);
+
+ @Override
+ public boolean execute()
+ {
+ PostState state = PostState.getState();
+ String text = state.getText();
+ int start = state.getSelectionStart();
+ int end = state.getSelectionEnd();
+ if(start == end && isReplaceCommand())
+ {
+ start = 0;
+ end = text.length();
+ }
+ String substring = text.substring(start, end);
+ String replacedText = build(substring);
+ StringBuilder builder = new StringBuilder(text);
+ String builtString = builder.replace(start, end, replacedText).toString();
+ PostState.PostStateTransaction transaction = state.beginTransaction();
+ int incremental = replacedText.length() - substring.length();
+ if(incremental > 0)
+ {
+ transaction.setCursor(end + incremental);
+ }
+ transaction.setText(builtString).commit();
+ return true;
+ }
+
+ public abstract boolean isReplaceCommand();
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandInsert.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandInsert.java
new file mode 100644
index 00000000..f1e1769e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandInsert.java
@@ -0,0 +1,71 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.post;
+
+import android.app.Activity;
+
+public class PostCommandInsert extends PostCommand
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String inserted;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public PostCommandInsert(Activity activity, String inserted)
+ {
+ super(activity);
+ this.inserted = inserted;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return inserted;
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isReplaceCommand()
+ {
+ return false;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public String build(String s)
+ {
+ return s + inserted;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandMakeAnonymous.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandMakeAnonymous.java
new file mode 100644
index 00000000..321f1df5
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandMakeAnonymous.java
@@ -0,0 +1,69 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.post;
+
+import android.app.Activity;
+import android.text.TextUtils;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.view.adapter.PostState;
+
+public class PostCommandMakeAnonymous extends PostCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public PostCommandMakeAnonymous(Activity activity)
+ {
+ super(activity);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_make_anonymous);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return !TextUtils.isEmpty(PostState.getState().getText());
+ }
+
+ @Override
+ public boolean isReplaceCommand()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public String build(String s)
+ {
+ return getActivity().getString(R.string.format_status_command_make_anonymous, s).trim();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandMorse.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandMorse.java
new file mode 100644
index 00000000..ff7c686c
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandMorse.java
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.post;
+
+import android.app.Activity;
+import android.text.TextUtils;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.util.Morse;
+import net.lacolaco.smileessence.view.adapter.PostState;
+
+public class PostCommandMorse extends PostCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public PostCommandMorse(Activity activity)
+ {
+ super(activity);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_post_morse);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return !TextUtils.isEmpty(PostState.getState().getText());
+ }
+
+ @Override
+ public boolean isReplaceCommand()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public String build(String s)
+ {
+ return Morse.jaToMorse(s);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandUseTemplate.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandUseTemplate.java
new file mode 100644
index 00000000..143f6c3e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandUseTemplate.java
@@ -0,0 +1,54 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.post;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.entity.Template;
+
+public class PostCommandUseTemplate extends PostCommandInsert
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Template template;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public PostCommandUseTemplate(Activity activity, Template template)
+ {
+ super(activity, template.text);
+ this.template = template;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public boolean execute()
+ {
+ template.count++;
+ template.save();
+ return super.execute();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandZekamashi.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandZekamashi.java
new file mode 100644
index 00000000..bf329777
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/post/PostCommandZekamashi.java
@@ -0,0 +1,82 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.post;
+
+import android.app.Activity;
+import android.text.TextUtils;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.view.adapter.PostState;
+
+public class PostCommandZekamashi extends PostCommand
+{
+
+ private static final String[] brackets = new String[]{"(,)", "(,)", "「,」", "[,]", "{,}", "<,>", "/,\\", "\,/"};
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public PostCommandZekamashi(Activity activity)
+ {
+ super(activity);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_post_zekamashi);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return !TextUtils.isEmpty(PostState.getState().getText());
+ }
+
+ @Override
+ public boolean isReplaceCommand()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public String build(String s)
+ {
+ StringBuilder builder = new StringBuilder(s);
+ builder.reverse();
+ String reversed = builder.toString();
+ String temp = "########TEMP########";
+ for(String bracket : brackets)
+ {
+ String first = bracket.split(",")[0];
+ String second = bracket.split(",")[1];
+ reversed = reversed.replace(first, temp).replace(second, first).replace(temp, second);
+ }
+ return reversed;
+
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommand.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommand.java
new file mode 100644
index 00000000..e9b6a103
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommand.java
@@ -0,0 +1,57 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.command.Command;
+import twitter4j.Status;
+
+public abstract class StatusCommand extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Status status;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommand(int key, Activity activity, Status status)
+ {
+ super(key, activity);
+ this.status = status;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ protected final Status getOriginalStatus()
+ {
+ return status.isRetweet() ? status.getRetweetedStatus() : status;
+ }
+
+ protected final Status getStatus()
+ {
+ return status;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandAddToIgnore.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandAddToIgnore.java
new file mode 100644
index 00000000..70807801
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandAddToIgnore.java
@@ -0,0 +1,66 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Status;
+
+public class StatusCommandAddToIgnore extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandAddToIgnore(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_add_to_ignore, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_add_to_ignore);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ StatusCache.getInstance().addToIgnoreStatus(getOriginalStatus().getId());
+ Notificator.publish(getActivity(), R.string.notice_add_to_ignore);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandAddToReply.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandAddToReply.java
new file mode 100644
index 00000000..49866450
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandAddToReply.java
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.Status;
+
+public class StatusCommandAddToReply extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandAddToReply(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_add_to_reply, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_add_to_reply);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ String text = String.format("@%s ", getOriginalStatus().getUser().getScreenName());
+ PostState.getState().beginTransaction().insertText(0, text).moveCursor(text.length()).commit();
+ Notificator.publish(getActivity(), R.string.notice_add_to_reply);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandClipboard.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandClipboard.java
new file mode 100644
index 00000000..6b52cd3f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandClipboard.java
@@ -0,0 +1,68 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Status;
+
+public class StatusCommandClipboard extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandClipboard(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_clipboard, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_clipboard);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ ClipboardManager manager = (ClipboardManager) getActivity().getSystemService(Activity.CLIPBOARD_SERVICE);
+ manager.setPrimaryClip(ClipData.newPlainText("tweet text", getOriginalStatus().getText()));
+ Notificator.publish(getActivity(), R.string.notice_copy_clipboard);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandCongratulate.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandCongratulate.java
new file mode 100644
index 00000000..7f76d582
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandCongratulate.java
@@ -0,0 +1,114 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.IConfirmable;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TweetBuilder;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.FavoriteTask;
+import net.lacolaco.smileessence.twitter.task.TweetTask;
+import twitter4j.Status;
+import twitter4j.StatusUpdate;
+import twitter4j.Twitter;
+
+import java.util.Random;
+
+public class StatusCommandCongratulate extends StatusCommand implements IConfirmable
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandCongratulate(Activity activity, Status status, Account account)
+ {
+ super(R.id.key_command_status_congratulate, activity, status);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_congratulate);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return !getOriginalStatus().getUser().isProtected();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public String build()
+ {
+ Status status = getOriginalStatus();
+ int favCount;
+ Random rand = new Random();
+ int r = rand.nextInt(100);
+ if(r < 50)
+ {
+ favCount = 50;
+ }
+ else if(r < 80)
+ {
+ favCount = 100;
+ }
+ else if(r < 90)
+ {
+ favCount = 250;
+ }
+ else if(r < 99)
+ {
+ favCount = 1000;
+ }
+ else
+ {
+ favCount = 10000;
+ }
+ return String.format("@%s Congrats on your %s ★ tweet! http://favstar.fm/t/%s",
+ status.getUser().getScreenName(), favCount, status.getId());
+ }
+
+ @Override
+ public boolean execute()
+ {
+ Status status = getOriginalStatus();
+ StatusUpdate update = new TweetBuilder().setText(build())
+ .setInReplyToStatusID(status.getId())
+ .build();
+ Twitter twitter = new TwitterApi(account).getTwitter();
+ new TweetTask(twitter, update, getActivity()).execute();
+ new FavoriteTask(twitter, status.getId(), getActivity()).execute();
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandCopy.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandCopy.java
new file mode 100644
index 00000000..c34df7ce
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandCopy.java
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.Status;
+
+public class StatusCommandCopy extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandCopy(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_copy, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_copy);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ PostState.newState().beginTransaction()
+ .setText(getOriginalStatus().getText())
+ .commitWithOpen((MainActivity) getActivity());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandFavAndRT.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandFavAndRT.java
new file mode 100644
index 00000000..16adae6e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandFavAndRT.java
@@ -0,0 +1,76 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.IConfirmable;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.FavoriteTask;
+import net.lacolaco.smileessence.twitter.task.RetweetTask;
+import twitter4j.Status;
+import twitter4j.User;
+
+public class StatusCommandFavAndRT extends StatusCommand implements IConfirmable
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandFavAndRT(Activity activity, Status status, Account account)
+ {
+ super(R.id.key_command_status_fav_and_rt, activity, status);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_fav_and_rt);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ User user = getOriginalStatus().getUser();
+ return !user.isProtected() && user.getId() != account.userID;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ new FavoriteTask(new TwitterApi(account).getTwitter(), getOriginalStatus().getId(), getActivity()).execute();
+ new RetweetTask(new TwitterApi(account).getTwitter(), getOriginalStatus().getId(), getActivity()).execute();
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandMakeAnonymous.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandMakeAnonymous.java
new file mode 100644
index 00000000..77cc03ab
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandMakeAnonymous.java
@@ -0,0 +1,97 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.IConfirmable;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TweetBuilder;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.FavoriteTask;
+import net.lacolaco.smileessence.twitter.task.TweetTask;
+import twitter4j.Status;
+import twitter4j.StatusUpdate;
+import twitter4j.Twitter;
+
+public class StatusCommandMakeAnonymous extends StatusCommand implements IConfirmable
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public StatusCommandMakeAnonymous(Activity activity, Status status, Account account)
+ {
+ super(R.id.key_command_status_make_anonymous, activity, status);
+ this.account = account;
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static String build(Activity activity, Status status, Account account)
+ {
+ String str = status.getText();
+ String header = "";
+ if(str.startsWith("."))
+ {
+ str = str.replaceFirst(".", "");
+ }
+ if(str.startsWith(String.format("@%s", account.screenName)))
+ {
+ str = str.replaceFirst(String.format("@%s", account.screenName), "").trim();
+ }
+ str = activity.getString(R.string.format_status_command_make_anonymous, str).trim();
+ return str;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_make_anonymous);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ StatusUpdate update = new TweetBuilder().setText(build(getActivity(), getOriginalStatus(), account)).build();
+ Twitter twitter = new TwitterApi(account).getTwitter();
+ new TweetTask(twitter, update, getActivity()).execute();
+ new FavoriteTask(twitter, getOriginalStatus().getId(), getActivity()).execute();
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandNanigaja.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandNanigaja.java
new file mode 100644
index 00000000..a373e80e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandNanigaja.java
@@ -0,0 +1,105 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.IConfirmable;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TweetBuilder;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.FavoriteTask;
+import net.lacolaco.smileessence.twitter.task.TweetTask;
+import twitter4j.Status;
+import twitter4j.StatusUpdate;
+import twitter4j.Twitter;
+
+public class StatusCommandNanigaja extends StatusCommand implements IConfirmable
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandNanigaja(Activity activity, Status status, Account account)
+ {
+ super(R.id.key_command_status_nanigaja, activity, status);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_nanigaja);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public String build()
+ {
+ Status status = getOriginalStatus();
+ String str = status.getText();
+ String header = "";
+ if(str.startsWith("."))
+ {
+ str = str.replaceFirst(".", "");
+ }
+ if(str.startsWith(String.format("@%s", account.screenName)))
+ {
+ str = str.replaceFirst(String.format("@%s", account.screenName), "").trim();
+ header = "@" + status.getUser().getScreenName();
+ }
+ str = String.format("%s %s", header, String.format(getFormatString(getActivity()), str)).trim();
+ return str;
+ }
+
+ @Override
+ public boolean execute()
+ {
+ Status status = getOriginalStatus();
+ StatusUpdate update = new TweetBuilder().setText(build())
+ .setInReplyToStatusID(status.getId())
+ .build();
+ Twitter twitter = new TwitterApi(account).getTwitter();
+ new TweetTask(twitter, update, getActivity()).execute();
+ new FavoriteTask(twitter, status.getId(), getActivity()).execute();
+ return true;
+ }
+
+ private String getFormatString(Activity activity)
+ {
+ return activity.getString(R.string.format_status_command_nanigaja);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenInBrowser.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenInBrowser.java
new file mode 100644
index 00000000..0cbed1ee
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenInBrowser.java
@@ -0,0 +1,64 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.CommandOpenURL;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import twitter4j.Status;
+
+public class StatusCommandOpenInBrowser extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandOpenInBrowser(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_open_in_browser, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_open_in_browser);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ return new CommandOpenURL(getActivity(), TwitterUtils.getStatusURL(getOriginalStatus())).execute();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenQuoteDialog.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenQuoteDialog.java
new file mode 100644
index 00000000..77a51696
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenQuoteDialog.java
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.QuoteDialogFragment;
+import twitter4j.Status;
+
+public class StatusCommandOpenQuoteDialog extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandOpenQuoteDialog(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_quote, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_quote);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ QuoteDialogFragment dialogFragment = new QuoteDialogFragment();
+ dialogFragment.setStatusID(getOriginalStatus().getId());
+ DialogHelper.showDialog(getActivity(), dialogFragment, "quoteDialog");
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenTalkView.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenTalkView.java
new file mode 100644
index 00000000..ee80092b
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandOpenTalkView.java
@@ -0,0 +1,73 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.TalkChainDialogFragment;
+import twitter4j.Status;
+
+public class StatusCommandOpenTalkView extends StatusCommand
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandOpenTalkView(Activity activity, Status status, Account account)
+ {
+ super(R.id.key_command_status_open_chain, activity, status);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_open_talk_view);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return getOriginalStatus().getInReplyToStatusId() >= 0;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ TalkChainDialogFragment dialogFragment = new TalkChainDialogFragment();
+ dialogFragment.setStatusID(getOriginalStatus().getId());
+ DialogHelper.showDialog(getActivity(), dialogFragment);
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandReplyToAll.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandReplyToAll.java
new file mode 100644
index 00000000..a4a815ac
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandReplyToAll.java
@@ -0,0 +1,78 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TweetBuilder;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.Status;
+
+public class StatusCommandReplyToAll extends StatusCommand
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandReplyToAll(Activity activity, Status status, Account account)
+ {
+ super(R.id.key_command_status_reply_to_all, activity, status);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_reply_to_all);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return TwitterUtils.getScreenNames(getOriginalStatus(), account.screenName).size() > 1;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ TweetBuilder builder = new TweetBuilder().addScreenNames(TwitterUtils.getScreenNames(getOriginalStatus(), account.screenName));
+ String text = builder.buildText();
+ PostState.newState().beginTransaction()
+ .setText(text)
+ .setCursor(text.length())
+ .commitWithOpen((MainActivity) getActivity());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandReview.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandReview.java
new file mode 100644
index 00000000..3d5d5a77
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandReview.java
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.ReviewDialogFragment;
+import twitter4j.Status;
+
+public class StatusCommandReview extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandReview(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_review, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_review);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return !getOriginalStatus().getUser().isProtected();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ ReviewDialogFragment dialogFragment = new ReviewDialogFragment();
+ dialogFragment.setStatusID(getOriginalStatus().getId());
+ DialogHelper.showDialog(getActivity(), dialogFragment);
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandSearchOnGoogle.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandSearchOnGoogle.java
new file mode 100644
index 00000000..b044e5ac
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandSearchOnGoogle.java
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.SearchOnGoogleDialogFragment;
+import twitter4j.Status;
+
+public class StatusCommandSearchOnGoogle extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandSearchOnGoogle(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_search_on_google, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_search_on_google);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ SearchOnGoogleDialogFragment dialogFragment = new SearchOnGoogleDialogFragment();
+ dialogFragment.setText(getOriginalStatus().getText());
+ DialogHelper.showDialog(getActivity(), dialogFragment);
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandShare.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandShare.java
new file mode 100644
index 00000000..1745cd39
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandShare.java
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import android.content.Intent;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.IntentUtils;
+import twitter4j.Status;
+
+public class StatusCommandShare extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandShare(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_share, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_share);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_SEND);
+ intent.setType("text/plain");
+ intent.putExtra(Intent.EXTRA_TEXT, TwitterUtils.getStatusSummary(getOriginalStatus()));
+ IntentUtils.startActivityIfFound(getActivity(), intent);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandTextQuote.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandTextQuote.java
new file mode 100644
index 00000000..d4cadff2
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandTextQuote.java
@@ -0,0 +1,71 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.twitter.TweetBuilder;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.Status;
+
+public class StatusCommandTextQuote extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandTextQuote(Activity activity, Status status)
+ {
+ super(-1, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_quote_text);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return !getStatus().getUser().isProtected();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ TweetBuilder builder = new TweetBuilder().setQuotation(getOriginalStatus());
+ PostState.newState().beginTransaction()
+ .setText(builder.buildText())
+ .setInReplyToStatusID(getOriginalStatus().getId())
+ .setCursor(0)
+ .commitWithOpen((MainActivity) getActivity());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandTofuBuster.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandTofuBuster.java
new file mode 100644
index 00000000..ffe587c4
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandTofuBuster.java
@@ -0,0 +1,79 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Status;
+
+public class StatusCommandTofuBuster extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandTofuBuster(Activity activity, Status status)
+ {
+ super(R.id.key_command_status_tofubuster, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_tofubuster);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ String ACTION_SHOW_TEXT = "com.product.kanzmrsw.tofubuster.ACTION_SHOW_TEXT";
+ String text = getOriginalStatus().getText();
+ Intent i = new Intent(ACTION_SHOW_TEXT);
+ i.putExtra(Intent.EXTRA_TEXT, text);
+ i.putExtra(Intent.EXTRA_SUBJECT, getActivity().getString(R.string.app_name));
+ i.putExtra("isCopyEnabled", true);
+ try
+ {
+ getActivity().startActivity(i);
+ }
+ catch(ActivityNotFoundException e)
+ {
+ new Notificator(getActivity(), R.string.notice_tofubuster_not_found).publish();
+ }
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandURLQuote.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandURLQuote.java
new file mode 100644
index 00000000..6fda35d3
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/status/StatusCommandURLQuote.java
@@ -0,0 +1,69 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.status;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.Status;
+
+public class StatusCommandURLQuote extends StatusCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusCommandURLQuote(Activity activity, Status status)
+ {
+ super(-1, activity, status);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_status_quote_url);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ String statusURL = TwitterUtils.getStatusURL(getOriginalStatus());
+ PostState.newState().beginTransaction()
+ .setText(statusURL)
+ .commitWithOpen((MainActivity) getActivity());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommand.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommand.java
new file mode 100644
index 00000000..861e101e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommand.java
@@ -0,0 +1,52 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.command.Command;
+import twitter4j.User;
+
+public abstract class UserCommand extends Command
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final User user;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommand(int key, Activity activity, User user)
+ {
+ super(key, activity);
+ this.user = user;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ protected User getUser()
+ {
+ return user;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandAddToReply.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandAddToReply.java
new file mode 100644
index 00000000..65e3edd9
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandAddToReply.java
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.User;
+
+public class UserCommandAddToReply extends UserCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandAddToReply(Activity activity, User user)
+ {
+ super(R.id.key_command_user_add_to_reply, activity, user);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_add_to_reply);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ String text = String.format("@%s ", getUser().getScreenName());
+ PostState.getState().beginTransaction().insertText(0, text).moveCursor(text.length()).commit();
+ Notificator.publish(getActivity(), R.string.notice_add_to_reply);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandBlock.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandBlock.java
new file mode 100644
index 00000000..020d2fb8
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandBlock.java
@@ -0,0 +1,72 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.IConfirmable;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.BlockTask;
+import twitter4j.User;
+
+public class UserCommandBlock extends UserCommand implements IConfirmable
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandBlock(Activity activity, User user, Account account)
+ {
+ super(R.id.key_command_user_block, activity, user);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_block);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return getUser().getId() != account.userID;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ new BlockTask(TwitterApi.getTwitter(account), getUser().getId(), getActivity()).execute();
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandIntroduce.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandIntroduce.java
new file mode 100644
index 00000000..77dd0f3f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandIntroduce.java
@@ -0,0 +1,68 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.User;
+
+public class UserCommandIntroduce extends UserCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandIntroduce(Activity activity, User user)
+ {
+ super(R.id.key_command_user_introduce, activity, user);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_introduce);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ PostState.newState().beginTransaction()
+ .setText(String.format(" (@%s)", getUser().getScreenName()))
+ .setCursor(0)
+ .commitWithOpen((MainActivity) getActivity());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenAclog.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenAclog.java
new file mode 100644
index 00000000..209d1fb0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenAclog.java
@@ -0,0 +1,64 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.CommandOpenURL;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import twitter4j.User;
+
+public class UserCommandOpenAclog extends UserCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandOpenAclog(Activity activity, User user)
+ {
+ super(R.id.key_command_user_open_aclog, activity, user);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_open_aclog);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ return new CommandOpenURL(getActivity(), TwitterUtils.getAclogTimelineURL(getUser().getScreenName())).execute();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenFavstar.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenFavstar.java
new file mode 100644
index 00000000..f4cf88dd
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenFavstar.java
@@ -0,0 +1,64 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.CommandOpenURL;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import twitter4j.User;
+
+public class UserCommandOpenFavstar extends UserCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandOpenFavstar(Activity activity, User user)
+ {
+ super(R.id.key_command_user_open_favstar, activity, user);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_open_favstar);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ return new CommandOpenURL(getActivity(), TwitterUtils.getFavstarRecentURL(getUser().getScreenName())).execute();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenTwilog.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenTwilog.java
new file mode 100644
index 00000000..43499f04
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandOpenTwilog.java
@@ -0,0 +1,64 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.CommandOpenURL;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import twitter4j.User;
+
+public class UserCommandOpenTwilog extends UserCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandOpenTwilog(Activity activity, User user)
+ {
+ super(R.id.key_command_user_open_twilog, activity, user);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_open_twilog);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ return new CommandOpenURL(getActivity(), TwitterUtils.getTwilogURL(getUser().getScreenName())).execute();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandReply.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandReply.java
new file mode 100644
index 00000000..04eeefe6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandReply.java
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.twitter.TweetBuilder;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.User;
+
+public class UserCommandReply extends UserCommand
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandReply(Activity activity, User user)
+ {
+ super(R.id.key_command_user_reply, activity, user);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_reply);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ String text = new TweetBuilder().addScreenName(getUser().getScreenName()).buildText();
+ PostState.newState().beginTransaction()
+ .setText(text)
+ .setCursor(text.length())
+ .commitWithOpen((MainActivity) getActivity());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandReportForSpam.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandReportForSpam.java
new file mode 100644
index 00000000..537300c4
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandReportForSpam.java
@@ -0,0 +1,72 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.IConfirmable;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.ReportForSpamTask;
+import twitter4j.User;
+
+public class UserCommandReportForSpam extends UserCommand implements IConfirmable
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandReportForSpam(Activity activity, User user, Account account)
+ {
+ super(R.id.key_command_user_r4s, activity, user);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_r4s);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return getUser().getId() != account.userID;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ new ReportForSpamTask(new TwitterApi(account).getTwitter(), getUser().getId(), getActivity()).execute();
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandSendMessage.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandSendMessage.java
new file mode 100644
index 00000000..b45765c5
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandSendMessage.java
@@ -0,0 +1,73 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.SendMessageDialogFragment;
+import twitter4j.User;
+
+public class UserCommandSendMessage extends UserCommand
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandSendMessage(Activity activity, User user, Account account)
+ {
+ super(R.id.key_command_user_send_message, activity, user);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_send_message);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return account.userID != getUser().getId();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ SendMessageDialogFragment dialogFragment = new SendMessageDialogFragment();
+ dialogFragment.setScreenName(getUser().getScreenName());
+ DialogHelper.showDialog(getActivity(), dialogFragment);
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandUnblock.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandUnblock.java
new file mode 100644
index 00000000..0d95b655
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/command/user/UserCommandUnblock.java
@@ -0,0 +1,72 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.command.user;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.IConfirmable;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.UnblockTask;
+import twitter4j.User;
+
+public class UserCommandUnblock extends UserCommand implements IConfirmable
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Account account;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserCommandUnblock(Activity activity, User user, Account account)
+ {
+ super(R.id.key_command_user_unblock, activity, user);
+ this.account = account;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public String getText()
+ {
+ return getActivity().getString(R.string.command_user_unblock);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return getUser().getId() != account.userID;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ @Override
+ public boolean execute()
+ {
+ new UnblockTask(new TwitterApi(account).getTwitter(), getUser().getId(), getActivity()).execute();
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/data/CommandSettingCache.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/CommandSettingCache.java
new file mode 100644
index 00000000..8862abc6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/CommandSettingCache.java
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.data;
+
+import net.lacolaco.smileessence.entity.CommandSetting;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+public class CommandSettingCache
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static CommandSettingCache instance = new CommandSettingCache();
+
+ private ConcurrentHashMap<Integer, Boolean> cache = new ConcurrentHashMap<>();
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private CommandSettingCache()
+ {
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static CommandSettingCache getInstance()
+ {
+ return instance;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public Boolean get(int id)
+ {
+ Boolean visibility = cache.get(Integer.valueOf(id));
+ return visibility != null ? visibility : true;
+ }
+
+ public void put(CommandSetting commandSetting)
+ {
+ cache.put(commandSetting.commandKey, commandSetting.visibility);
+ }
+
+ public boolean remove(int id)
+ {
+ return cache.remove(Integer.valueOf(id));
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/data/DirectMessageCache.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/DirectMessageCache.java
new file mode 100644
index 00000000..a4f626ca
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/DirectMessageCache.java
@@ -0,0 +1,98 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.data;
+
+import twitter4j.DirectMessage;
+
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class DirectMessageCache
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static DirectMessageCache instance = new DirectMessageCache();
+
+ private ConcurrentHashMap<Long, DirectMessage> cache = new ConcurrentHashMap<>();
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private DirectMessageCache()
+ {
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static DirectMessageCache getInstance()
+ {
+ return instance;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ /**
+ * Get all elements
+ *
+ * @return cached all message
+ */
+ public Collection<DirectMessage> all()
+ {
+ return cache.values();
+ }
+
+ /**
+ * Get message by id
+ *
+ * @param id message id
+ * @return cached value
+ */
+ public DirectMessage get(long id)
+ {
+ return cache.get(id);
+ }
+
+ /**
+ * Put message into cache
+ *
+ * @param message
+ * @return the previous value associated with key, or null if there was no mapping for key
+ */
+ public DirectMessage put(DirectMessage message)
+ {
+ return cache.put(message.getId(), message);
+ }
+
+ /**
+ * Remove message by id
+ *
+ * @param id message id
+ * @return removed message
+ */
+ public DirectMessage remove(long id)
+ {
+ return cache.remove(id);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/data/FavoriteCache.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/FavoriteCache.java
new file mode 100644
index 00000000..2d31dc40
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/FavoriteCache.java
@@ -0,0 +1,99 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.data;
+
+import twitter4j.Status;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+public class FavoriteCache
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static FavoriteCache instance = new FavoriteCache();
+
+ private ConcurrentHashMap<Long, Boolean> cache = new ConcurrentHashMap<>();
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private FavoriteCache()
+ {
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static FavoriteCache getInstance()
+ {
+ return instance;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ /**
+ * Get status by id
+ */
+ public boolean get(long id)
+ {
+ Boolean favorited = cache.get(id);
+ return favorited != null ? favorited : false;
+ }
+
+ /**
+ * Put status into cache
+ */
+ public void put(Status status)
+ {
+ if(!status.isRetweet())
+ {
+ cache.put(status.getId(), status.isFavorited());
+ }
+ }
+
+ public void put(Status status, boolean favorited)
+ {
+ if(status.isRetweet())
+ {
+ cache.put(status.getRetweetedStatus().getId(), favorited);
+ }
+ else
+ {
+ cache.put(status.getId(), favorited);
+ }
+ }
+
+ public void put(long id, boolean favorited)
+ {
+ cache.put(id, favorited);
+ }
+
+ /**
+ * Remove favorite by id
+ */
+ public boolean remove(long id)
+ {
+ return cache.remove(id);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/data/ImageCache.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/ImageCache.java
new file mode 100644
index 00000000..7f74ca71
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/ImageCache.java
@@ -0,0 +1,101 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.data;
+
+import android.graphics.Bitmap;
+import android.util.LruCache;
+import com.android.volley.RequestQueue;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.*;
+
+public class ImageCache implements ImageLoader.ImageCache
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static ImageCache instance = new ImageCache();
+ private LruCache<String, Bitmap> cache;
+ private RequestQueue requestQueue;
+ private ImageLoader imageLoader;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private ImageCache()
+ {
+ int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
+ int cacheSize = maxMemory / 8;
+ cache = new LruCache<>(cacheSize);
+ requestQueue = new RequestQueue(new NoCache(), new BasicNetwork(new HurlStack()));
+ imageLoader = new ImageLoader(requestQueue, this);
+ requestQueue.start();
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static ImageCache getInstance()
+ {
+ return instance;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface ImageCache ---------------------
+
+ @Override
+ public Bitmap getBitmap(String url)
+ {
+ return cache.get(url);
+ }
+
+ @Override
+ public void putBitmap(String url, Bitmap bitmap)
+ {
+ cache.put(url, bitmap);
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public ImageLoader.ImageContainer requestBitmap(String imageURL)
+ {
+ return imageLoader.get(imageURL, new ImageLoader.ImageListener()
+ {
+ @Override
+ public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate)
+ {
+ }
+
+ @Override
+ public void onErrorResponse(VolleyError error)
+ {
+ }
+ });
+ }
+
+ public void setImageToView(String imageURL, NetworkImageView view)
+ {
+ view.setImageUrl(imageURL, imageLoader);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/data/StatusCache.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/StatusCache.java
new file mode 100644
index 00000000..8f949754
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/StatusCache.java
@@ -0,0 +1,108 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.data;
+
+import twitter4j.Status;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class StatusCache
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static StatusCache instance = new StatusCache();
+
+ private ConcurrentHashMap<Long, Status> cache = new ConcurrentHashMap<>();
+
+ private ConcurrentLinkedQueue<Long> ignoreIDs = new ConcurrentLinkedQueue<>();
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private StatusCache()
+ {
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static StatusCache getInstance()
+ {
+ return instance;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void addToIgnoreStatus(long id)
+ {
+ ignoreIDs.add(id);
+ }
+
+ /**
+ * Get status by id
+ *
+ * @param id status id
+ * @return cached value
+ */
+ public Status get(long id)
+ {
+ return cache.get(id);
+ }
+
+ public boolean isIgnored(long id)
+ {
+ return ignoreIDs.contains(id);
+ }
+
+ /**
+ * Put status into cache
+ *
+ * @param status
+ * @return the previous value associated with key, or null if there was no mapping for key
+ */
+ public Status put(Status status)
+ {
+ if(status.isRetweet())
+ {
+ put(status.getRetweetedStatus());
+ }
+ if(cache.containsKey(status.getId()))
+ {
+ cache.remove(status.getId());
+ }
+ return cache.put(status.getId(), status);
+ }
+
+ /**
+ * Remove status by id
+ *
+ * @param id status id
+ * @return removed status
+ */
+ public Status remove(long id)
+ {
+ return cache.remove(id);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/data/UserCache.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/UserCache.java
new file mode 100644
index 00000000..4b5864f6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/UserCache.java
@@ -0,0 +1,105 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.data;
+
+import twitter4j.User;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class UserCache
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static UserCache instance = new UserCache();
+
+ private ConcurrentHashMap<Long, User> cache = new ConcurrentHashMap<>();
+
+ private ConcurrentLinkedQueue<Long> invisibleIDs = new ConcurrentLinkedQueue<>();
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private UserCache()
+ {
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static UserCache getInstance()
+ {
+ return instance;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ /**
+ * Get user by id
+ *
+ * @param id user id
+ * @return cached value
+ */
+ public User get(long id)
+ {
+ return cache.get(id);
+ }
+
+ public boolean isInvisibleUserID(long id)
+ {
+ return invisibleIDs.contains(Long.valueOf(id));
+ }
+
+ /**
+ * Put user into cache
+ *
+ * @param user
+ * @return the previous value associated with key, or null if there was no mapping for key
+ */
+ public User put(User user)
+ {
+ return cache.put(user.getId(), user);
+ }
+
+ public void putInvisibleUser(long id)
+ {
+ invisibleIDs.add(id);
+ }
+
+ /**
+ * Remove user by id
+ *
+ * @param id user id
+ * @return removed user
+ */
+ public User remove(long id)
+ {
+ return cache.remove(id);
+ }
+
+ public void removeInvisibleUser(long id)
+ {
+ invisibleIDs.remove(Long.valueOf(id));
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/data/UserListCache.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/UserListCache.java
new file mode 100644
index 00000000..ea2e3c34
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/data/UserListCache.java
@@ -0,0 +1,79 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.data;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class UserListCache
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static UserListCache instance = new UserListCache();
+
+ private ConcurrentLinkedQueue<String> cache = new ConcurrentLinkedQueue<>();
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private UserListCache()
+ {
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static UserListCache getInstance()
+ {
+ return instance;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public String[] getAll()
+ {
+ return cache.toArray(new String[cache.size()]);
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void clear()
+ {
+ cache.clear();
+ }
+
+ /**
+ * Put userList into cache
+ *
+ * @param userList
+ */
+ public void put(String userList)
+ {
+ cache.add(userList);
+ }
+
+ public void remove(String userList)
+ {
+ cache.remove(userList);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/Account.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/Account.java
new file mode 100644
index 00000000..9c941840
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/Account.java
@@ -0,0 +1,69 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.entity;
+
+import com.activeandroid.Model;
+import com.activeandroid.annotation.Column;
+import com.activeandroid.annotation.Table;
+import com.activeandroid.query.Delete;
+
+@Table(name = "Accounts")
+public class Account extends Model
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ @Column(name = "Token", notNull = true)
+ public String accessToken;
+ @Column(name = "Secret", notNull = true)
+ public String accessSecret;
+ @Column(name = "UserID", notNull = true)
+ public long userID;
+ @Column(name = "ScreenName", notNull = true)
+ public String screenName;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public Account()
+ {
+ super();
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public Account(String token, String tokenSecret, long userID, String screenName)
+ {
+ super();
+ this.accessToken = token;
+ this.accessSecret = tokenSecret;
+ this.userID = userID;
+ this.screenName = screenName;
+ }
+
+ public static void deleteAll()
+ {
+ new Delete().from(Account.class).execute();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/CommandSetting.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/CommandSetting.java
new file mode 100644
index 00000000..78a16bf6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/CommandSetting.java
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.entity;
+
+import com.activeandroid.Model;
+import com.activeandroid.annotation.Column;
+import com.activeandroid.annotation.Table;
+import com.activeandroid.query.Select;
+
+import java.util.List;
+
+@Table(name = "Commands")
+public class CommandSetting extends Model
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ @Column(name = "CommandKey")
+ public int commandKey;
+ @Column(name = "Visibility")
+ public boolean visibility;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public CommandSetting()
+ {
+ super();
+ }
+
+ public CommandSetting(int commandKey, boolean visibility)
+ {
+ super();
+ this.commandKey = commandKey;
+ this.visibility = visibility;
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static List<CommandSetting> getAll()
+ {
+ return new Select().from(CommandSetting.class).execute();
+ }
+
+ public static CommandSetting selectByKey(int key)
+ {
+ return new Select().from(CommandSetting.class).where("CommandKey = ?", key).executeSingle();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/ExtractionWord.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/ExtractionWord.java
new file mode 100644
index 00000000..404686fa
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/ExtractionWord.java
@@ -0,0 +1,85 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.entity;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import com.activeandroid.Model;
+import com.activeandroid.annotation.Column;
+import com.activeandroid.annotation.Table;
+import com.activeandroid.query.Select;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.viewmodel.IViewModel;
+
+import java.util.List;
+
+@Table(name = "Extraction")
+public class ExtractionWord extends Model implements IViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ @Column(name = "Text", notNull = true)
+ public String text;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public ExtractionWord()
+ {
+ super();
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public ExtractionWord(String text)
+ {
+ super();
+ this.text = text;
+ }
+
+ public static List<ExtractionWord> getAll()
+ {
+ return new Select().from(ExtractionWord.class).execute();
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface IViewModel ---------------------
+
+ @Override
+ public View getView(Activity activity, LayoutInflater inflater, View convertedView)
+ {
+ if(convertedView == null)
+ {
+ convertedView = inflater.inflate(R.layout.menu_item_simple_text, null);
+ }
+ TextView textView = (TextView) convertedView.findViewById(R.id.textView_menuItem_simple);
+ textView.setText(this.text);
+ return convertedView;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/SearchQuery.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/SearchQuery.java
new file mode 100644
index 00000000..2d248c98
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/SearchQuery.java
@@ -0,0 +1,88 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.entity;
+
+import com.activeandroid.Model;
+import com.activeandroid.annotation.Column;
+import com.activeandroid.annotation.Table;
+import com.activeandroid.query.Select;
+
+import java.util.Date;
+import java.util.List;
+
+@Table(name = "SearchQueries")
+public class SearchQuery extends Model
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ @Column(name = "Query", unique = true)
+ public String query;
+
+ @Column(name = "CreatedAt")
+ public Date createdAt;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public SearchQuery()
+ {
+ super();
+ }
+
+ public SearchQuery(String query, Date createdAt)
+ {
+ this.query = query;
+ this.createdAt = createdAt;
+ }
+
+ public static List<SearchQuery> getAll()
+ {
+ return new Select().from(SearchQuery.class).orderBy("CreatedAt DESC").execute();
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ /**
+ * @param query
+ * @return
+ */
+ public static boolean saveIfNotFound(String query)
+ {
+ if(findByQuery(query) != null)
+ {
+ return false;
+ }
+ else
+ {
+ new SearchQuery(query, new Date()).save();
+ return true;
+ }
+ }
+
+ public static SearchQuery findByQuery(String query)
+ {
+ return new Select().from(SearchQuery.class).where("Query = ?", query).executeSingle();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/Template.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/Template.java
new file mode 100644
index 00000000..276dc30f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/entity/Template.java
@@ -0,0 +1,88 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.entity;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import com.activeandroid.Model;
+import com.activeandroid.annotation.Column;
+import com.activeandroid.annotation.Table;
+import com.activeandroid.query.Select;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.viewmodel.IViewModel;
+
+import java.util.List;
+
+@Table(name = "Templates")
+public class Template extends Model implements IViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ @Column(name = "Text", notNull = true)
+ public String text;
+ @Column(name = "Count")
+ public int count;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public Template()
+ {
+ super();
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public Template(String text, int count)
+ {
+ super();
+ this.text = text;
+ this.count = count;
+ }
+
+ public static List<Template> getAll()
+ {
+ return new Select().from(Template.class).orderBy("COUNT DESC").execute();
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface IViewModel ---------------------
+
+ @Override
+ public View getView(Activity activity, LayoutInflater inflater, View convertedView)
+ {
+ if(convertedView == null)
+ {
+ convertedView = inflater.inflate(R.layout.menu_item_simple_text, null);
+ }
+ TextView textView = (TextView) convertedView.findViewById(R.id.textView_menuItem_simple);
+ textView.setText(this.text);
+ return convertedView;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/logging/Logger.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/logging/Logger.java
new file mode 100644
index 00000000..d0ea41d4
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/logging/Logger.java
@@ -0,0 +1,62 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.logging;
+
+import android.util.Log;
+
+public class Logger
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final String TAG = "SmileEssence";
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static void debug(Object message)
+ {
+ Log.d(TAG, String.valueOf(message));
+ }
+
+ public static void info(Object message)
+ {
+ Log.i(TAG, String.valueOf(message));
+ }
+
+ public static void error(Object message)
+ {
+ Log.e(TAG, String.valueOf(message));
+ }
+
+ public static void warn(Object message)
+ {
+ Log.w(TAG, String.valueOf(message));
+ }
+
+ public static void verbose(Object message)
+ {
+ Log.v(TAG, String.valueOf(message));
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/notification/NotificationType.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/notification/NotificationType.java
new file mode 100644
index 00000000..a02c1984
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/notification/NotificationType.java
@@ -0,0 +1,31 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.notification;
+
+public enum NotificationType
+{
+ INFO,
+ ALERT;
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/notification/Notificator.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/notification/Notificator.java
new file mode 100644
index 00000000..7815823d
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/notification/Notificator.java
@@ -0,0 +1,169 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.notification;
+
+import android.app.Activity;
+import android.widget.Toast;
+import de.keyboardsurfer.android.widget.crouton.Configuration;
+import de.keyboardsurfer.android.widget.crouton.Crouton;
+import de.keyboardsurfer.android.widget.crouton.Style;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.util.UIHandler;
+
+public class Notificator
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final int DURATION = 1000;
+ private static boolean isRunning;
+ private Activity activity;
+ private String text;
+ private NotificationType type;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public Notificator(Activity activity, int resID)
+ {
+ this(activity, resID, NotificationType.INFO);
+ }
+
+ public Notificator(Activity activity, String text)
+ {
+ this(activity, text, NotificationType.INFO);
+ }
+
+ public Notificator(Activity activity, int resID, NotificationType type)
+ {
+ this(activity, activity.getString(resID), type);
+ }
+
+ public Notificator(Activity activity, String text, NotificationType type)
+ {
+ this.activity = activity;
+ this.text = text;
+ this.type = type;
+ }
+
+ public static void startNotification()
+ {
+ isRunning = true;
+ }
+
+ public static void stopNotification()
+ {
+ isRunning = false;
+ Crouton.cancelAllCroutons();
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ /**
+ * Notify self on cronton or toast.
+ */
+ public static void publish(Activity activity, int resID)
+ {
+ publish(activity, activity.getString(resID));
+ }
+
+ public static void publish(Activity activity, String text)
+ {
+ new Notificator(activity, text, NotificationType.INFO).publish();
+ }
+
+ public static void publish(Activity activity, int resID, NotificationType type)
+ {
+ publish(activity, activity.getString(resID), type);
+ }
+
+ public static void publish(Activity activity, String text, NotificationType type)
+ {
+ new Notificator(activity, text, type).publish();
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private Style getStyle()
+ {
+ Configuration.Builder conf = new Configuration.Builder();
+ conf.setDuration(DURATION);
+ Style.Builder style = new Style.Builder();
+ style.setConfiguration(conf.build());
+ switch(type)
+ {
+ case INFO:
+ {
+ style.setBackgroundColorValue(Style.holoBlueLight);
+ break;
+ }
+ case ALERT:
+ {
+ style.setBackgroundColorValue(Style.holoRedLight);
+ break;
+ }
+ }
+ return style.build();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public Crouton makeCrouton()
+ {
+ return Crouton.makeText(activity, text, getStyle());
+ }
+
+ public Toast makeToast()
+ {
+ return Toast.makeText(activity, text, Toast.LENGTH_LONG);
+ }
+
+ /**
+ * Notify self on cronton or toast.
+ */
+ public void publish()
+ {
+ if(activity == null || activity.isFinishing())
+ {
+ return;
+ }
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ if(isRunning)
+ {
+ Logger.debug(String.format("notify by crouton %s", text));
+ makeCrouton().show();
+ }
+ else
+ {
+ Logger.debug(String.format("notify by toast %s", text));
+ makeToast().show();
+ }
+ }
+ }.post();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/AppPreferenceHelper.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/AppPreferenceHelper.java
new file mode 100644
index 00000000..be492c14
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/AppPreferenceHelper.java
@@ -0,0 +1,42 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.preference;
+
+import android.content.Context;
+
+public class AppPreferenceHelper extends SharedPreferenceHelper
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final String FILE_NAME = "AppPreference";
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public AppPreferenceHelper(Context context)
+ {
+ super(context, FILE_NAME);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/SharedPreferenceHelper.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/SharedPreferenceHelper.java
new file mode 100644
index 00000000..7b26d200
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/SharedPreferenceHelper.java
@@ -0,0 +1,128 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.preference;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import java.util.Set;
+
+public class SharedPreferenceHelper
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ protected final Context context;
+ protected final String fileName;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public SharedPreferenceHelper(Context context, String fileName)
+ {
+ this.context = context;
+ this.fileName = fileName;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ protected SharedPreferences getPref()
+ {
+ return context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public boolean getValue(String key, boolean defaultValue)
+ {
+ return getPref().getBoolean(key, defaultValue);
+ }
+
+ public int getValue(String key, int defaultValue)
+ {
+ return Integer.valueOf(getPref().getString(key, String.valueOf(defaultValue)));
+ }
+
+ public float getValue(String key, float defaultValue)
+ {
+ return Float.valueOf(getPref().getString(key, String.valueOf(defaultValue)));
+ }
+
+ public long getValue(String key, long defaultValue)
+ {
+ return Long.valueOf(getPref().getString(key, String.valueOf(defaultValue)));
+ }
+
+ public String getValue(String key, String defaultValue)
+ {
+ return getPref().getString(key, defaultValue);
+ }
+
+ public Set<String> getValue(String key, Set<String> defaultValue)
+ {
+ return getPref().getStringSet(key, defaultValue);
+ }
+
+ public boolean putValue(String key, boolean value)
+ {
+ SharedPreferences.Editor editor = getPref().edit();
+ editor.putBoolean(key, value);
+ return editor.commit();
+ }
+
+ public boolean putValue(String key, int value)
+ {
+ SharedPreferences.Editor editor = getPref().edit();
+ editor.putString(key, String.valueOf(value));
+ return editor.commit();
+ }
+
+ public boolean putValue(String key, float value)
+ {
+ SharedPreferences.Editor editor = getPref().edit();
+ editor.putString(key, String.valueOf(value));
+ return editor.commit();
+ }
+
+ public boolean putValue(String key, long value)
+ {
+ SharedPreferences.Editor editor = getPref().edit();
+ editor.putString(key, String.valueOf(value));
+ return editor.commit();
+ }
+
+ public boolean putValue(String key, String value)
+ {
+ SharedPreferences.Editor editor = getPref().edit();
+ editor.putString(key, value);
+ return editor.commit();
+ }
+
+ public boolean putValue(String key, Set<String> value)
+ {
+ SharedPreferences.Editor editor = getPref().edit();
+ editor.putStringSet(key, value);
+ return editor.commit();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/UserPreferenceHelper.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/UserPreferenceHelper.java
new file mode 100644
index 00000000..c65cdea8
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/preference/UserPreferenceHelper.java
@@ -0,0 +1,155 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.preference;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+
+import java.util.Set;
+
+public class UserPreferenceHelper extends SharedPreferenceHelper
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final int TEXT_SIZE_MIN = 8;
+ public static final int TEXT_SIZE_MAX = 24;
+ public static final int TIMELINES_MIN = 1;
+ public static final int TIMELINES_MAX = 200;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserPreferenceHelper(Context context)
+ {
+ super(context, null);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ protected SharedPreferences getPref()
+ {
+ return PreferenceManager.getDefaultSharedPreferences(context);
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public boolean getValue(int keyID, boolean defaultValue)
+ {
+ return getString(keyID) != null ? super.getValue(getString(keyID), defaultValue) : defaultValue;
+ }
+
+ public int getValue(int keyID, int defaultValue)
+ {
+ return getString(keyID) != null ? super.getValue(getString(keyID), defaultValue) : defaultValue;
+ }
+
+ public float getValue(int keyID, float defaultValue)
+ {
+ return getString(keyID) != null ? super.getValue(getString(keyID), defaultValue) : defaultValue;
+ }
+
+ public long getValue(int keyID, long defaultValue)
+ {
+ return getString(keyID) != null ? super.getValue(getString(keyID), defaultValue) : defaultValue;
+ }
+
+ public String getValue(int keyID, String defaultValue)
+ {
+ return getString(keyID) != null ? super.getValue(getString(keyID), defaultValue) : defaultValue;
+ }
+
+ public Set<String> getValue(int keyID, Set<String> defaultValue)
+ {
+ return getString(keyID) != null ? super.getValue(getString(keyID), defaultValue) : defaultValue;
+ }
+
+ public boolean putValue(int keyID, boolean value)
+ {
+ if(getString(keyID) == null)
+ {
+ return false;
+ }
+ return super.putValue(getString(keyID), value);
+ }
+
+ public boolean putValue(int keyID, int value)
+ {
+ if(getString(keyID) == null)
+ {
+ return false;
+ }
+ return super.putValue(getString(keyID), value);
+ }
+
+ public boolean putValue(int keyID, float value)
+ {
+ if(getString(keyID) == null)
+ {
+ return false;
+ }
+ return super.putValue(getString(keyID), value);
+ }
+
+ public boolean putValue(int keyID, long value)
+ {
+ if(getString(keyID) == null)
+ {
+ return false;
+ }
+ return super.putValue(getString(keyID), value);
+ }
+
+ public boolean putValue(int keyID, String value)
+ {
+ if(getString(keyID) == null)
+ {
+ return false;
+ }
+ return super.putValue(getString(keyID), value);
+ }
+
+ public boolean putValue(int keyID, Set<String> value)
+ {
+ if(getString(keyID) == null)
+ {
+ return false;
+ }
+ return super.putValue(getString(keyID), value);
+ }
+
+ protected String getString(int resID)
+ {
+ try
+ {
+ return context.getString(resID);
+ }
+ catch(Exception e)
+ {
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/OAuthSession.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/OAuthSession.java
new file mode 100644
index 00000000..4e7950ea
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/OAuthSession.java
@@ -0,0 +1,88 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter;
+
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.twitter.task.AccessTokenTask;
+import net.lacolaco.smileessence.twitter.task.RequestTokenTask;
+import twitter4j.Twitter;
+import twitter4j.TwitterFactory;
+import twitter4j.auth.AccessToken;
+import twitter4j.auth.RequestToken;
+
+import java.util.concurrent.ExecutionException;
+
+public class OAuthSession
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String CALLBACK_OAUTH = "oauth://smileessence";
+ public static final String KEY_TOKEN = "token";
+ public static final String KEY_TOKEN_SECRET = "tokenSecret";
+ public static final String KEY_SCREEN_NAME = "screenName";
+ public static final String KEY_USER_ID = "userID";
+ private static final String OAUTH_VERIFIER = "oauth_verifier";
+ private RequestToken requestToken;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public String getAuthorizationURL()
+ {
+ Twitter twitter = new TwitterFactory().getInstance();
+ RequestTokenTask task = new RequestTokenTask(twitter);
+ task.execute();
+ try
+ {
+ requestToken = task.get();
+ return requestToken.getAuthorizationURL();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ Logger.error(e.getMessage());
+ return null;
+ }
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public AccessToken getAccessToken(String pinCode)
+ {
+ Twitter twitter = new TwitterFactory().getInstance();
+ AccessTokenTask task = new AccessTokenTask(twitter, requestToken, pinCode);
+ task.execute();
+ try
+ {
+ return task.get();
+ }
+ catch(InterruptedException | ExecutionException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/StatusFilter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/StatusFilter.java
new file mode 100644
index 00000000..082ed20b
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/StatusFilter.java
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter;
+
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.entity.ExtractionWord;
+import net.lacolaco.smileessence.view.adapter.StatusListAdapter;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+
+import java.util.regex.Pattern;
+
+public class StatusFilter
+{
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static void filter(MainActivity activity, StatusViewModel status)
+ {
+ extract(activity, status);
+ }
+
+ private static void extract(MainActivity activity, StatusViewModel status)
+ {
+ if(status.isRetweet())
+ {
+ return;
+ }
+ Pattern pattern;
+ for(ExtractionWord word : ExtractionWord.getAll())
+ {
+ pattern = Pattern.compile(word.text);
+ if(pattern.matcher(status.getText()).find())
+ {
+ addToMentions(activity, status);
+ }
+ }
+ }
+
+ private static void addToMentions(MainActivity activity, StatusViewModel status)
+ {
+ StatusListAdapter adapter = (StatusListAdapter) activity.getListAdapter(MainActivity.ADAPTER_MENTIONS);
+ adapter.addToTop(status);
+ adapter.update();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/TweetBuilder.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/TweetBuilder.java
new file mode 100644
index 00000000..957bbbe6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/TweetBuilder.java
@@ -0,0 +1,123 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter;
+
+import android.text.TextUtils;
+import twitter4j.Status;
+import twitter4j.StatusUpdate;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class TweetBuilder
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private String text = "";
+ private ArrayList<String> screenNameList = new ArrayList<>();
+ private long inReplyToStatusID = -1;
+ private String mediaPath = "";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public TweetBuilder setInReplyToStatusID(long inReplyToStatusID)
+ {
+ this.inReplyToStatusID = inReplyToStatusID;
+ return this;
+ }
+
+ public TweetBuilder setMediaPath(String mediaPath)
+ {
+ this.mediaPath = mediaPath;
+ return this;
+ }
+
+ public TweetBuilder setQuotation(Status status)
+ {
+ return setText(String.format(" RT @%s: %s", status.getUser().getScreenName(), status.getText()));
+ }
+
+ public TweetBuilder setText(String text)
+ {
+ this.text = text;
+ return this;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public TweetBuilder addScreenName(String screenName)
+ {
+ screenNameList.add(screenName);
+ return this;
+ }
+
+ public TweetBuilder addScreenNames(Collection<String> screenNames)
+ {
+ screenNameList.addAll(screenNames);
+ return this;
+ }
+
+ public TweetBuilder appendText(String str)
+ {
+ return setText(text + str);
+ }
+
+ public StatusUpdate build()
+ {
+ StatusUpdate statusUpdate = new StatusUpdate(buildText());
+ if(inReplyToStatusID >= 0)
+ {
+ statusUpdate.setInReplyToStatusId(inReplyToStatusID);
+ }
+ if(!TextUtils.isEmpty(mediaPath))
+ {
+ File media = new File(mediaPath);
+ if(media.exists())
+ {
+ statusUpdate.setMedia(media);
+ }
+ }
+ return statusUpdate;
+ }
+
+ public String buildText()
+ {
+ StringBuilder builder = new StringBuilder();
+
+ for(String screenName : screenNameList)
+ {
+ builder.append(String.format("@%s ", screenName));
+ }
+ builder.append(text);
+ return builder.toString();
+ }
+
+ public TweetBuilder setQuotation(Status status, String text)
+ {
+ return setText(String.format("%s RT @%s: %s", text, status.getUser().getScreenName(), status.getText()));
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/TwitterApi.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/TwitterApi.java
new file mode 100644
index 00000000..fb642801
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/TwitterApi.java
@@ -0,0 +1,79 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter;
+
+import net.lacolaco.smileessence.entity.Account;
+import twitter4j.Twitter;
+import twitter4j.TwitterFactory;
+import twitter4j.TwitterStream;
+import twitter4j.TwitterStreamFactory;
+import twitter4j.auth.AccessToken;
+
+public class TwitterApi
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final int MEDIA_SIZE_LIMIT = 2 * 1024 * 1024;
+ private final String token;
+ private final String tokenSecret;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public TwitterApi(Account account)
+ {
+ this.token = account.accessToken;
+ this.tokenSecret = account.accessSecret;
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public TwitterApi(String token, String tokenSecret)
+ {
+ this.token = token;
+ this.tokenSecret = tokenSecret;
+ }
+
+ public static Twitter getTwitter(Account account)
+ {
+ return new TwitterApi(account).getTwitter();
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public Twitter getTwitter()
+ {
+ Twitter twitter = new TwitterFactory().getInstance();
+ twitter.setOAuthAccessToken(new AccessToken(token, tokenSecret));
+ return twitter;
+ }
+
+ public TwitterStream getTwitterStream()
+ {
+ TwitterStream stream = new TwitterStreamFactory().getInstance();
+ stream.setOAuthAccessToken(new AccessToken(token, tokenSecret));
+ return stream;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/UserStreamListener.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/UserStreamListener.java
new file mode 100644
index 00000000..6dee87e5
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/UserStreamListener.java
@@ -0,0 +1,334 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter;
+
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.*;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import net.lacolaco.smileessence.view.adapter.MessageListAdapter;
+import net.lacolaco.smileessence.view.adapter.StatusListAdapter;
+import net.lacolaco.smileessence.viewmodel.EnumEvent;
+import net.lacolaco.smileessence.viewmodel.EventViewModel;
+import net.lacolaco.smileessence.viewmodel.MessageViewModel;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.*;
+
+public class UserStreamListener implements twitter4j.UserStreamListener, ConnectionLifeCycleListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final MainActivity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserStreamListener(MainActivity activity)
+ {
+ this.activity = activity;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private long getMyID()
+ {
+ return activity.getCurrentAccount().userID;
+ }
+
+ private int getPagerCount()
+ {
+ return activity.getPagerAdapter().getCount();
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface ConnectionLifeCycleListener ---------------------
+
+ @Override
+ public void onConnect()
+ {
+ activity.setStreaming(true);
+ new Notificator(activity, R.string.notice_stream_connect).publish();
+ }
+
+ @Override
+ public void onDisconnect()
+ {
+ activity.setStreaming(false);
+ new Notificator(activity, R.string.notice_stream_disconnect).publish();
+ }
+
+ @Override
+ public void onCleanUp()
+ {
+ }
+
+ // --------------------- Interface StatusListener ---------------------
+
+ @Override
+ public void onStatus(Status status)
+ {
+ StatusCache.getInstance().put(status);
+ if(isIgnoredStatus(status))
+ {
+ return;
+ }
+ StatusViewModel viewModel = new StatusViewModel(status, activity.getCurrentAccount());
+ addToHome(viewModel);
+ if(status.isRetweet())
+ {
+ if(viewModel.isRetweetOfMe())
+ {
+ addToHistory(new EventViewModel(EnumEvent.RETWEETED, status.getUser(), status));
+ }
+ }
+ else if(viewModel.isMention())
+ {
+ addToMentions(viewModel);
+ EventViewModel mentioned = new EventViewModel(EnumEvent.MENTIONED, status.getUser(), status);
+ Notificator.publish(activity, mentioned.getFormattedString(activity));
+ }
+ StatusFilter.filter(activity, viewModel);
+ FavoriteCache.getInstance().put(status);
+ }
+
+ @Override
+ public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice)
+ {
+ for(CustomListAdapter<?> adapter : activity.getListAdapters())
+ {
+ if(adapter != null && adapter instanceof StatusListAdapter)
+ {
+ StatusListAdapter statusListAdapter = (StatusListAdapter) adapter;
+ statusListAdapter.removeByStatusID(statusDeletionNotice.getStatusId());
+ statusListAdapter.updateForce();
+ }
+ }
+ StatusCache.getInstance().remove(statusDeletionNotice.getStatusId());
+ }
+
+ @Override
+ public void onTrackLimitationNotice(int numberOfLimitedStatuses)
+ {
+ }
+
+ @Override
+ public void onScrubGeo(long userId, long upToStatusId)
+ {
+ }
+
+ @Override
+ public void onStallWarning(StallWarning warning)
+ {
+ }
+
+ // --------------------- Interface StreamListener ---------------------
+
+ @Override
+ public void onException(Exception ex)
+ {
+ net.lacolaco.smileessence.logging.Logger.error(ex.toString());
+ }
+
+ // --------------------- Interface UserStreamListener ---------------------
+
+ @Override
+ public void onDeletionNotice(long directMessageId, long userId)
+ {
+ MessageListAdapter messages = (MessageListAdapter) activity.getListAdapter(MainActivity.ADAPTER_MESSAGES);
+ messages.removeByMessageID(directMessageId);
+ messages.updateForce();
+ DirectMessageCache.getInstance().remove(directMessageId);
+ }
+
+ @Override
+ public void onFriendList(long[] friendIds)
+ {
+ }
+
+ @Override
+ public void onFavorite(User source, User target, Status favoritedStatus)
+ {
+ StatusCache.getInstance().put(favoritedStatus);
+ if(isMe(target))
+ {
+ addToHistory(new EventViewModel(EnumEvent.FAVORITED, source, favoritedStatus));
+ }
+ if(isMe(source))
+ {
+ FavoriteCache.getInstance().put(favoritedStatus, true);
+ activity.getListAdapter(MainActivity.ADAPTER_HOME).update();
+ activity.getListAdapter(MainActivity.ADAPTER_MENTIONS).update();
+ }
+ }
+
+ @Override
+ public void onUnfavorite(User source, User target, Status unfavoritedStatus)
+ {
+ StatusCache.getInstance().put(unfavoritedStatus);
+ boolean unfavNoticeEnabled = activity.getUserPreferenceHelper().getValue(R.string.key_setting_notify_on_unfavorited, true);
+ if(isMe(target) && unfavNoticeEnabled)
+ {
+ addToHistory(new EventViewModel(EnumEvent.UNFAVORITED, source, unfavoritedStatus));
+ }
+ if(isMe(source))
+ {
+ FavoriteCache.getInstance().put(unfavoritedStatus, false);
+ activity.getListAdapter(MainActivity.ADAPTER_HOME).update();
+ activity.getListAdapter(MainActivity.ADAPTER_MENTIONS).update();
+ }
+ }
+
+ @Override
+ public void onFollow(User source, User followedUser)
+ {
+ UserCache.getInstance().put(source);
+ UserCache.getInstance().put(followedUser);
+ if(isMe(followedUser))
+ {
+ addToHistory(new EventViewModel(EnumEvent.FOLLOWED, source));
+ }
+ }
+
+ @Override
+ public void onUnfollow(User source, User unfollowedUser)
+ {
+ }
+
+ @Override
+ public void onDirectMessage(DirectMessage directMessage)
+ {
+ DirectMessageCache.getInstance().put(directMessage);
+ if(isMe(directMessage.getRecipient()))
+ {
+ addToHistory(new EventViewModel(EnumEvent.RECEIVE_MESSAGE, directMessage.getSender()));
+ }
+ MessageViewModel message = new MessageViewModel(directMessage, activity.getCurrentAccount());
+ addToMessages(message);
+ }
+
+ @Override
+ public void onUserListMemberAddition(User addedMember, User listOwner, UserList list)
+ {
+ }
+
+ @Override
+ public void onUserListMemberDeletion(User deletedMember, User listOwner, UserList list)
+ {
+ }
+
+ @Override
+ public void onUserListSubscription(User subscriber, User listOwner, UserList list)
+ {
+ UserListCache.getInstance().put(list.getFullName());
+ }
+
+ @Override
+ public void onUserListUnsubscription(User subscriber, User listOwner, UserList list)
+ {
+ UserListCache.getInstance().remove(list.getFullName());
+ }
+
+ @Override
+ public void onUserListCreation(User listOwner, UserList list)
+ {
+ UserListCache.getInstance().put(list.getFullName());
+ }
+
+ @Override
+ public void onUserListUpdate(User listOwner, UserList list)
+ {
+ }
+
+ @Override
+ public void onUserListDeletion(User listOwner, UserList list)
+ {
+ UserListCache.getInstance().remove(list.getFullName());
+ }
+
+ @Override
+ public void onUserProfileUpdate(User updatedUser)
+ {
+ }
+
+ @Override
+ public void onBlock(User source, User blockedUser)
+ {
+ if(isMe(blockedUser))
+ {
+ addToHistory(new EventViewModel(EnumEvent.BLOCKED, source));
+ }
+ }
+
+ @Override
+ public void onUnblock(User source, User unblockedUser)
+ {
+ if(isMe(unblockedUser))
+ {
+ addToHistory(new EventViewModel(EnumEvent.UNBLOCKED, source));
+ }
+ }
+
+ private void addToHistory(EventViewModel mentioned)
+ {
+ CustomListAdapter<?> history = activity.getListAdapter(MainActivity.ADAPTER_HISTORY);
+ Notificator.publish(activity, mentioned.getFormattedString(activity));
+ history.addToTop(mentioned);
+ history.update();
+ }
+
+ private void addToHome(StatusViewModel viewModel)
+ {
+ StatusListAdapter home = (StatusListAdapter) activity.getListAdapter(MainActivity.ADAPTER_HOME);
+ home.addToTop(viewModel);
+ home.update();
+ }
+
+ private void addToMentions(StatusViewModel viewModel)
+ {
+ StatusListAdapter mentions = (StatusListAdapter) activity.getListAdapter(MainActivity.ADAPTER_MENTIONS);
+ mentions.addToTop(viewModel);
+ mentions.update();
+ }
+
+ private void addToMessages(MessageViewModel message)
+ {
+ MessageListAdapter messages = (MessageListAdapter) activity.getListAdapter(MainActivity.ADAPTER_MESSAGES);
+ messages.addToTop(message);
+ messages.update();
+ }
+
+ private boolean isIgnoredStatus(Status status)
+ {
+ return status.isRetweet() && StatusCache.getInstance().isIgnored(status.getRetweetedStatus().getId());
+ }
+
+ private boolean isMe(User user)
+ {
+ return user.getId() == getMyID();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/AccessTokenTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/AccessTokenTask.java
new file mode 100644
index 00000000..f6b59658
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/AccessTokenTask.java
@@ -0,0 +1,62 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.auth.AccessToken;
+import twitter4j.auth.RequestToken;
+
+public class AccessTokenTask extends TwitterTask<AccessToken>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final RequestToken requestToken;
+ private final String pinCode;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public AccessTokenTask(Twitter twitter, RequestToken requestToken, String pinCode)
+ {
+ super(twitter);
+ this.requestToken = requestToken;
+ this.pinCode = pinCode;
+ }
+
+ @Override
+ protected AccessToken doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.getOAuthAccessToken(requestToken, pinCode);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/BlockIDsTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/BlockIDsTask.java
new file mode 100644
index 00000000..df5155d5
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/BlockIDsTask.java
@@ -0,0 +1,83 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.IDs;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BlockIDsTask extends TwitterTask<Long[]>
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public BlockIDsTask(Twitter twitter)
+ {
+ super(twitter);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(Long[] blockIDs)
+ {
+ for(Long blockID : blockIDs)
+ {
+ UserCache.getInstance().putInvisibleUser(blockID);
+ }
+ }
+
+ @Override
+ protected Long[] doInBackground(Void... params)
+ {
+ try
+ {
+ List<Long> idList = new ArrayList<>();
+ long cursor = -1;
+ do
+ {
+ IDs blocksIDs = twitter.getBlocksIDs(cursor);
+ cursor = blocksIDs.getNextCursor();
+ for(long id : blocksIDs.getIDs())
+ {
+ idList.add(id);
+ }
+ }
+ while(cursor != 0);
+
+ return idList.toArray(new Long[idList.size()]);
+ }
+ catch(TwitterException e)
+ {
+ Logger.error(e);
+ return new Long[0];
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/BlockTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/BlockTask.java
new file mode 100644
index 00000000..96244d3c
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/BlockTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.User;
+
+public class BlockTask extends TwitterTask<User>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long userID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public BlockTask(Twitter twitter, long userID, Activity activity)
+ {
+ super(twitter);
+ this.userID = userID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(User user)
+ {
+ if(user != null)
+ {
+ UserCache.getInstance().put(user);
+ new Notificator(activity, R.string.notice_block_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_block_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected User doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.users().createBlock(userID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DeleteMessageTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DeleteMessageTask.java
new file mode 100644
index 00000000..40dd20cd
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DeleteMessageTask.java
@@ -0,0 +1,85 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.DirectMessageCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.DirectMessage;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class DeleteMessageTask extends TwitterTask<DirectMessage>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long messageID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public DeleteMessageTask(Twitter twitter, long messageID, Activity activity)
+ {
+ super(twitter);
+ this.messageID = messageID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(DirectMessage message)
+ {
+ if(message != null)
+ {
+ DirectMessageCache.getInstance().put(message);
+ new Notificator(activity, R.string.notice_message_delete_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_message_delete_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected DirectMessage doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.directMessages().destroyDirectMessage(messageID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DeleteStatusTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DeleteStatusTask.java
new file mode 100644
index 00000000..e4f4a19a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DeleteStatusTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class DeleteStatusTask extends TwitterTask<Status>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long statusID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public DeleteStatusTask(Twitter twitter, long statusID, Activity activity)
+ {
+ super(twitter);
+ this.statusID = statusID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status status)
+ {
+ if(status != null)
+ {
+ StatusCache.getInstance().remove(status.getId());
+ new Notificator(activity, R.string.notice_status_delete_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_status_delete_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected twitter4j.Status doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.tweets().destroyStatus(statusID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DirectMessagesTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DirectMessagesTask.java
new file mode 100644
index 00000000..f8a574fa
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/DirectMessagesTask.java
@@ -0,0 +1,102 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.DirectMessageCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.*;
+
+public class DirectMessagesTask extends TwitterTask<DirectMessage[]>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Activity activity;
+ private final Paging paging;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ protected DirectMessagesTask(Twitter twitter, Activity activity)
+ {
+ this(twitter, activity, null);
+ }
+
+ public DirectMessagesTask(Twitter twitter, Activity activity, Paging paging)
+ {
+ super(twitter);
+ this.activity = activity;
+ this.paging = paging;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(DirectMessage[] directMessages)
+ {
+ if(directMessages.length != 0)
+ {
+ for(DirectMessage message : directMessages)
+ {
+ DirectMessageCache.getInstance().put(message);
+ }
+ }
+ }
+
+ @Override
+ protected DirectMessage[] doInBackground(Void... params)
+ {
+ ResponseList<DirectMessage> responseList;
+ try
+ {
+ if(paging == null)
+ {
+ responseList = twitter.directMessages().getDirectMessages();
+ }
+ else
+ {
+ responseList = twitter.directMessages().getDirectMessages(paging);
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ if(e.exceededRateLimitation())
+ {
+ Notificator.publish(activity, R.string.notice_error_rate_limit, NotificationType.ALERT);
+ }
+ else
+ {
+ Notificator.publish(activity, R.string.notice_error_get_messages, NotificationType.ALERT);
+ }
+ return new DirectMessage[0];
+ }
+ return responseList.toArray(new DirectMessage[responseList.size()]);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/FavoriteTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/FavoriteTask.java
new file mode 100644
index 00000000..8e509ba5
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/FavoriteTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class FavoriteTask extends TwitterTask<Status>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long statusID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public FavoriteTask(Twitter twitter, long statusID, Activity activity)
+ {
+ super(twitter);
+ this.statusID = statusID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status status)
+ {
+ if(status != null)
+ {
+ StatusCache.getInstance().put(status);
+ new Notificator(activity, R.string.notice_favorite_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_favorite_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected twitter4j.Status doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.favorites().createFavorite(statusID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/FollowTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/FollowTask.java
new file mode 100644
index 00000000..bea00f8c
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/FollowTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.User;
+
+public class FollowTask extends TwitterTask<User>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long userID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public FollowTask(Twitter twitter, long userID, Activity activity)
+ {
+ super(twitter);
+ this.userID = userID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(User user)
+ {
+ if(user != null)
+ {
+ UserCache.getInstance().put(user);
+ new Notificator(activity, R.string.notice_follow_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_follow_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected User doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.friendsFollowers().createFriendship(userID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/GetUserListsTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/GetUserListsTask.java
new file mode 100644
index 00000000..dbc80637
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/GetUserListsTask.java
@@ -0,0 +1,73 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.data.UserListCache;
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.UserList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GetUserListsTask extends TwitterTask<UserList[]>
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public GetUserListsTask(Twitter twitter)
+ {
+ super(twitter);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(UserList[] lists)
+ {
+ for(UserList list : lists)
+ {
+ UserListCache.getInstance().put(list.getFullName());
+ }
+ }
+
+ @Override
+ protected UserList[] doInBackground(Void... params)
+ {
+ try
+ {
+ List<UserList> userLists = new ArrayList<>();
+
+ userLists.addAll(twitter.list().getUserLists(twitter.getId()));
+ return userLists.toArray(new UserList[userLists.size()]);
+ }
+ catch(TwitterException e)
+ {
+ Logger.error(e);
+ return new UserList[0];
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/HomeTimelineTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/HomeTimelineTask.java
new file mode 100644
index 00000000..59dfdeb0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/HomeTimelineTask.java
@@ -0,0 +1,104 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.FavoriteCache;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.*;
+
+public class HomeTimelineTask extends TwitterTask<Status[]>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Paging paging;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public HomeTimelineTask(Twitter twitter, Activity activity)
+ {
+ this(twitter, activity, null);
+ }
+
+ public HomeTimelineTask(Twitter twitter, Activity activity, Paging paging)
+ {
+ super(twitter);
+ this.activity = activity;
+ this.paging = paging;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ if(statuses.length != 0)
+ {
+ for(twitter4j.Status status : statuses)
+ {
+ StatusCache.getInstance().put(status);
+ FavoriteCache.getInstance().put(status);
+ }
+ }
+ }
+
+ @Override
+ protected twitter4j.Status[] doInBackground(Void... params)
+ {
+ ResponseList<twitter4j.Status> responseList;
+ try
+ {
+ if(paging == null)
+ {
+ responseList = twitter.timelines().getHomeTimeline();
+ }
+ else
+ {
+ responseList = twitter.timelines().getHomeTimeline(paging);
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ if(e.exceededRateLimitation())
+ {
+ Notificator.publish(activity, R.string.notice_error_rate_limit, NotificationType.ALERT);
+ }
+ else
+ {
+ Notificator.publish(activity, R.string.notice_error_get_home, NotificationType.ALERT);
+ }
+ return new twitter4j.Status[0];
+ }
+ return responseList.toArray(new twitter4j.Status[responseList.size()]);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/MentionsTimelineTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/MentionsTimelineTask.java
new file mode 100644
index 00000000..be9378d3
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/MentionsTimelineTask.java
@@ -0,0 +1,104 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.FavoriteCache;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.*;
+
+public class MentionsTimelineTask extends TwitterTask<Status[]>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Activity activity;
+ private final Paging paging;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ protected MentionsTimelineTask(Twitter twitter, Activity activity)
+ {
+ this(twitter, activity, null);
+ }
+
+ public MentionsTimelineTask(Twitter twitter, Activity activity, Paging paging)
+ {
+ super(twitter);
+ this.activity = activity;
+ this.paging = paging;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ if(statuses.length != 0)
+ {
+ for(twitter4j.Status status : statuses)
+ {
+ StatusCache.getInstance().put(status);
+ FavoriteCache.getInstance().put(status);
+ }
+ }
+ }
+
+ @Override
+ protected twitter4j.Status[] doInBackground(Void... params)
+ {
+ ResponseList<twitter4j.Status> responseList;
+ try
+ {
+ if(paging == null)
+ {
+ responseList = twitter.timelines().getMentionsTimeline();
+ }
+ else
+ {
+ responseList = twitter.timelines().getMentionsTimeline(paging);
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ if(e.exceededRateLimitation())
+ {
+ Notificator.publish(activity, R.string.notice_error_rate_limit, NotificationType.ALERT);
+ }
+ else
+ {
+ Notificator.publish(activity, R.string.notice_error_get_mentions, NotificationType.ALERT);
+ }
+ return new twitter4j.Status[0];
+ }
+ return responseList.toArray(new twitter4j.Status[responseList.size()]);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/MutesIDsTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/MutesIDsTask.java
new file mode 100644
index 00000000..86c6effe
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/MutesIDsTask.java
@@ -0,0 +1,83 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.IDs;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MutesIDsTask extends TwitterTask<Long[]>
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MutesIDsTask(Twitter twitter)
+ {
+ super(twitter);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(Long[] mutesIDs)
+ {
+ for(Long mutesID : mutesIDs)
+ {
+ UserCache.getInstance().putInvisibleUser(mutesID);
+ }
+ }
+
+ @Override
+ protected Long[] doInBackground(Void... params)
+ {
+ try
+ {
+ List<Long> idList = new ArrayList<>();
+ long cursor = -1;
+ do
+ {
+ IDs mutesIDs = twitter.getMutesIDs(cursor);
+ cursor = mutesIDs.getNextCursor();
+ for(long id : mutesIDs.getIDs())
+ {
+ idList.add(id);
+ }
+ }
+ while(cursor != 0);
+
+ return idList.toArray(new Long[idList.size()]);
+ }
+ catch(TwitterException e)
+ {
+ Logger.error(e);
+ return new Long[0];
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ReportForSpamTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ReportForSpamTask.java
new file mode 100644
index 00000000..cdb04158
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ReportForSpamTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.User;
+
+public class ReportForSpamTask extends TwitterTask<User>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long userID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public ReportForSpamTask(Twitter twitter, long userID, Activity activity)
+ {
+ super(twitter);
+ this.userID = userID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(User user)
+ {
+ if(user != null)
+ {
+ UserCache.getInstance().put(user);
+ new Notificator(activity, R.string.notice_r4s_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_r4s_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected User doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.spamReporting().reportSpam(userID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/RequestTokenTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/RequestTokenTask.java
new file mode 100644
index 00000000..ed79b0eb
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/RequestTokenTask.java
@@ -0,0 +1,59 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.auth.RequestToken;
+
+public class RequestTokenTask extends TwitterTask<RequestToken>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public RequestTokenTask(Twitter twitter)
+ {
+ super(twitter);
+ }
+
+ @Override
+ protected RequestToken doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.getOAuthRequestToken();
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/RetweetTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/RetweetTask.java
new file mode 100644
index 00000000..a3073026
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/RetweetTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class RetweetTask extends TwitterTask<Status>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long statusID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public RetweetTask(Twitter twitter, long statusID, Activity activity)
+ {
+ super(twitter);
+ this.statusID = statusID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status status)
+ {
+ if(status != null)
+ {
+ StatusCache.getInstance().put(status);
+ new Notificator(activity, R.string.notice_retweet_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_retweet_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected twitter4j.Status doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.tweets().retweetStatus(statusID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SearchTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SearchTask.java
new file mode 100644
index 00000000..4611d0ce
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SearchTask.java
@@ -0,0 +1,113 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.content.res.Configuration;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.FavoriteCache;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import twitter4j.Query;
+import twitter4j.QueryResult;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class SearchTask extends TwitterTask<QueryResult>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final MainActivity activity;
+ private final Query query;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public SearchTask(Twitter twitter, String queryString, MainActivity activity)
+ {
+ this(twitter, getBaseQuery(activity, queryString), activity);
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public SearchTask(Twitter twitter, Query query, MainActivity activity)
+ {
+ super(twitter);
+ this.activity = activity;
+ this.query = query;
+ }
+
+ public static Query getBaseQuery(MainActivity activity, String queryString)
+ {
+ Configuration config = activity.getResources().getConfiguration();
+ Query query = new Query();
+ query.setQuery(queryString);
+ query.setLang(config.locale.getLanguage());
+ query.setCount(TwitterUtils.getPagingCount(activity));
+ query.setResultType(Query.RECENT);
+ return query;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(QueryResult queryResult)
+ {
+ if(queryResult != null)
+ {
+ for(twitter4j.Status status : queryResult.getTweets())
+ {
+ StatusCache.getInstance().put(status);
+ FavoriteCache.getInstance().put(status);
+ }
+ }
+ }
+
+ @Override
+ protected QueryResult doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.search(query);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.debug(e);
+ if(e.exceededRateLimitation())
+ {
+ Notificator.publish(activity, R.string.notice_error_rate_limit, NotificationType.ALERT);
+ }
+ else
+ {
+ Notificator.publish(activity, R.string.notice_error_search, NotificationType.ALERT);
+ }
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SendMessageTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SendMessageTask.java
new file mode 100644
index 00000000..b394f960
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SendMessageTask.java
@@ -0,0 +1,87 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.DirectMessageCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.DirectMessage;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class SendMessageTask extends TwitterTask<DirectMessage>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String userID;
+ private final String text;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public SendMessageTask(Twitter twitter, String screenName, String text, Activity activity)
+ {
+ super(twitter);
+ this.userID = screenName;
+ this.text = text;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(DirectMessage message)
+ {
+ if(message != null)
+ {
+ DirectMessageCache.getInstance().put(message);
+ new Notificator(activity, R.string.notice_message_send_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_message_send_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected DirectMessage doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.directMessages().sendDirectMessage(userID, text);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SentDirectMessagesTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SentDirectMessagesTask.java
new file mode 100644
index 00000000..10711c01
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/SentDirectMessagesTask.java
@@ -0,0 +1,102 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.DirectMessageCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.*;
+
+public class SentDirectMessagesTask extends TwitterTask<DirectMessage[]>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Activity activity;
+ private final Paging paging;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ protected SentDirectMessagesTask(Twitter twitter, Activity activity)
+ {
+ this(twitter, activity, null);
+ }
+
+ public SentDirectMessagesTask(Twitter twitter, Activity activity, Paging paging)
+ {
+ super(twitter);
+ this.activity = activity;
+ this.paging = paging;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(DirectMessage[] directMessages)
+ {
+ if(directMessages.length != 0)
+ {
+ for(DirectMessage message : directMessages)
+ {
+ DirectMessageCache.getInstance().put(message);
+ }
+ }
+ }
+
+ @Override
+ protected DirectMessage[] doInBackground(Void... params)
+ {
+ ResponseList<DirectMessage> responseList;
+ try
+ {
+ if(paging == null)
+ {
+ responseList = twitter.directMessages().getSentDirectMessages();
+ }
+ else
+ {
+ responseList = twitter.directMessages().getSentDirectMessages(paging);
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ if(e.exceededRateLimitation())
+ {
+ Notificator.publish(activity, R.string.notice_error_rate_limit, NotificationType.ALERT);
+ }
+ else
+ {
+ Notificator.publish(activity, R.string.notice_error_get_messages, NotificationType.ALERT);
+ }
+ return new DirectMessage[0];
+ }
+ return responseList.toArray(new DirectMessage[responseList.size()]);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowDirectMessageTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowDirectMessageTask.java
new file mode 100644
index 00000000..f2ba8432
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowDirectMessageTask.java
@@ -0,0 +1,73 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.data.DirectMessageCache;
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.DirectMessage;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class ShowDirectMessageTask extends TwitterTask<DirectMessage>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long messageID;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public ShowDirectMessageTask(Twitter twitter, long messageID)
+ {
+ super(twitter);
+ this.messageID = messageID;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(DirectMessage directMessage)
+ {
+ if(directMessage != null)
+ {
+ DirectMessageCache.getInstance().put(directMessage);
+ }
+ }
+
+ @Override
+ protected DirectMessage doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.directMessages().showDirectMessage(messageID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowFriendshipTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowFriendshipTask.java
new file mode 100644
index 00000000..f013288c
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowFriendshipTask.java
@@ -0,0 +1,77 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.Relationship;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class ShowFriendshipTask extends TwitterTask<Relationship>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long userID;
+ private final String screenName;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public ShowFriendshipTask(Twitter twitter, long userID)
+ {
+ super(twitter);
+ this.userID = userID;
+ this.screenName = null;
+ }
+
+ public ShowFriendshipTask(Twitter twitter, String screenName)
+ {
+ super(twitter);
+ this.screenName = screenName;
+ this.userID = -1;
+ }
+
+ @Override
+ protected Relationship doInBackground(Void... params)
+ {
+ try
+ {
+ if(screenName != null)
+ {
+ return twitter.friendsFollowers().showFriendship(twitter.getScreenName(), screenName);
+ }
+ else
+ {
+ return twitter.friendsFollowers().showFriendship(twitter.getId(), userID);
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowStatusTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowStatusTask.java
new file mode 100644
index 00000000..8206e6bf
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowStatusTask.java
@@ -0,0 +1,73 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class ShowStatusTask extends TwitterTask<Status>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long id;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public ShowStatusTask(Twitter twitter, long id)
+ {
+ super(twitter);
+ this.id = id;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status status)
+ {
+ if(status != null)
+ {
+ StatusCache.getInstance().put(status);
+ }
+ }
+
+ @Override
+ protected twitter4j.Status doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.tweets().showStatus(id);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowUserTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowUserTask.java
new file mode 100644
index 00000000..555bdfd1
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/ShowUserTask.java
@@ -0,0 +1,89 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.User;
+
+public class ShowUserTask extends TwitterTask<User>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long userID;
+ private final String screenName;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public ShowUserTask(Twitter twitter, long userID)
+ {
+ super(twitter);
+ this.userID = userID;
+ this.screenName = null;
+ }
+
+ public ShowUserTask(Twitter twitter, String screenName)
+ {
+ super(twitter);
+ this.screenName = screenName;
+ this.userID = -1;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(User user)
+ {
+ if(user != null)
+ {
+ UserCache.getInstance().put(user);
+ }
+ }
+
+ @Override
+ protected User doInBackground(Void... params)
+ {
+ try
+ {
+ if(screenName != null)
+ {
+ return twitter.users().showUser(screenName);
+ }
+ else
+ {
+ return twitter.users().showUser(userID);
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/TweetTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/TweetTask.java
new file mode 100644
index 00000000..9f769dc7
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/TweetTask.java
@@ -0,0 +1,167 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Environment;
+import android.text.TextUtils;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import twitter4j.Status;
+import twitter4j.StatusUpdate;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class TweetTask extends TwitterTask<Status>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final StatusUpdate update;
+ private final String mediaPath;
+ private final Activity activity;
+ private String tempFilePath;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public TweetTask(Twitter twitter, StatusUpdate update, Activity activity)
+ {
+ this(twitter, update, null, activity);
+ }
+
+ public TweetTask(Twitter twitter, StatusUpdate update, String mediaPath, Activity activity)
+ {
+ super(twitter);
+ this.update = update;
+ this.mediaPath = mediaPath;
+ this.activity = activity;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public File getMediaFile()
+ {
+ File file = new File(mediaPath);
+ boolean resizeFlag = new UserPreferenceHelper(activity).getValue(R.string.key_setting_resize_post_image, false);
+ if(file.length() >= TwitterApi.MEDIA_SIZE_LIMIT && resizeFlag)
+ {
+ BitmapFactory.Options opt = new BitmapFactory.Options();
+ opt.inJustDecodeBounds = true; //decoder is not return bitmap but set option
+ BitmapFactory.decodeFile(mediaPath, opt);
+ tempFilePath = Environment.getExternalStorageDirectory() + "/temp.jpg";
+ File compressedFile = new File(tempFilePath);
+ FileOutputStream fos = null;
+ try
+ {
+ fos = new FileOutputStream(compressedFile);
+ float ratio = (float) file.length() / (float) TwitterApi.MEDIA_SIZE_LIMIT;
+ BitmapFactory.Options resizeOpt = new BitmapFactory.Options();
+ resizeOpt.inPurgeable = true;
+ resizeOpt.inSampleSize = (int) Math.ceil(ratio);
+ Bitmap bitmap = BitmapFactory.decodeFile(mediaPath, resizeOpt);
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
+ bitmap.recycle();
+ return compressedFile;
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ Logger.error(e);
+ }
+ finally
+ {
+ try
+ {
+ fos.close();
+ }
+ catch(IOException e)
+ {
+ e.printStackTrace();
+ Logger.error(e);
+ }
+ }
+ }
+ return file;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status status)
+ {
+ if(status != null)
+ {
+ StatusCache.getInstance().put(status);
+ new Notificator(activity, R.string.notice_tweet_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_tweet_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected twitter4j.Status doInBackground(Void... params)
+ {
+ try
+ {
+ if(TextUtils.isEmpty(mediaPath))
+ {
+ return twitter.tweets().updateStatus(update);
+ }
+ else
+ {
+ File mediaFile = getMediaFile();
+ if(mediaFile.exists())
+ {
+ update.setMedia(mediaFile);
+ }
+ twitter4j.Status status = twitter.tweets().updateStatus(update);
+ if(tempFilePath != null)
+ {
+ new File(tempFilePath).delete();
+ }
+ return status;
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/TwitterTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/TwitterTask.java
new file mode 100644
index 00000000..f9dfdca1
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/TwitterTask.java
@@ -0,0 +1,43 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.os.AsyncTask;
+import twitter4j.Twitter;
+
+public abstract class TwitterTask<T> extends AsyncTask<Void, Void, T>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ protected Twitter twitter;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ protected TwitterTask(Twitter twitter)
+ {
+ this.twitter = twitter;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnblockTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnblockTask.java
new file mode 100644
index 00000000..1c0cb6bf
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnblockTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.User;
+
+public class UnblockTask extends TwitterTask<User>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long userID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UnblockTask(Twitter twitter, long userID, Activity activity)
+ {
+ super(twitter);
+ this.userID = userID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(User user)
+ {
+ if(user != null)
+ {
+ UserCache.getInstance().put(user);
+ new Notificator(activity, R.string.notice_unblock_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_unblock_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected User doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.users().destroyBlock(userID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnfavoriteTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnfavoriteTask.java
new file mode 100644
index 00000000..ef2a660b
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnfavoriteTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class UnfavoriteTask extends TwitterTask<Status>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long statusID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UnfavoriteTask(Twitter twitter, long statusID, Activity activity)
+ {
+ super(twitter);
+ this.statusID = statusID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status status)
+ {
+ if(status != null)
+ {
+ StatusCache.getInstance().put(status);
+ new Notificator(activity, R.string.notice_unfavorite_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_unfavorite_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected twitter4j.Status doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.favorites().destroyFavorite(statusID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnfollowTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnfollowTask.java
new file mode 100644
index 00000000..b75a1043
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UnfollowTask.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+import twitter4j.User;
+
+public class UnfollowTask extends TwitterTask<User>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long userID;
+ private final Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UnfollowTask(Twitter twitter, long userID, Activity activity)
+ {
+ super(twitter);
+ this.userID = userID;
+ this.activity = activity;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(User user)
+ {
+ if(user != null)
+ {
+ UserCache.getInstance().put(user);
+ new Notificator(activity, R.string.notice_unfollow_succeeded).publish();
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_unfollow_failed, NotificationType.ALERT).publish();
+ }
+ }
+
+ @Override
+ protected User doInBackground(Void... params)
+ {
+ try
+ {
+ return twitter.friendsFollowers().destroyFriendship(userID);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UserListStatusesTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UserListStatusesTask.java
new file mode 100644
index 00000000..4ece998e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UserListStatusesTask.java
@@ -0,0 +1,87 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.FavoriteCache;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import twitter4j.*;
+
+public class UserListStatusesTask extends TwitterTask<Status[]>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String listFullName;
+ private final MainActivity activity;
+ private final Paging paging;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserListStatusesTask(Twitter twitter, String listFullName, MainActivity activity)
+ {
+ this(twitter, listFullName, activity, TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity)));
+ }
+
+ public UserListStatusesTask(Twitter twitter, String listFullName, MainActivity activity, Paging paging)
+ {
+ super(twitter);
+ this.listFullName = listFullName;
+ this.activity = activity;
+ this.paging = paging;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ for(twitter4j.Status status : statuses)
+ {
+ StatusCache.getInstance().put(status);
+ FavoriteCache.getInstance().put(status);
+ }
+ }
+
+ @Override
+ protected twitter4j.Status[] doInBackground(Void... params)
+ {
+ ResponseList<twitter4j.Status> responseList;
+ try
+ {
+ String[] strings = listFullName.split("/");
+ responseList = twitter.list().getUserListStatuses(strings[0], strings[1], paging);
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return new twitter4j.Status[0];
+ }
+ return responseList.toArray(new twitter4j.Status[responseList.size()]);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UserTimelineTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UserTimelineTask.java
new file mode 100644
index 00000000..0426c2a9
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/task/UserTimelineTask.java
@@ -0,0 +1,88 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.task;
+
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.logging.Logger;
+import twitter4j.*;
+
+public class UserTimelineTask extends TwitterTask<Status[]>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final long userID;
+ private final Paging paging;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserTimelineTask(Twitter twitter, long userID)
+ {
+ this(twitter, userID, null);
+ }
+
+ public UserTimelineTask(Twitter twitter, long userID, Paging paging)
+ {
+ super(twitter);
+ this.userID = userID;
+ this.paging = paging;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ for(twitter4j.Status status : statuses)
+ {
+ StatusCache.getInstance().put(status);
+ }
+
+ }
+
+ @Override
+ protected twitter4j.Status[] doInBackground(Void... params)
+ {
+ ResponseList<twitter4j.Status> responseList;
+ try
+ {
+ if(paging == null)
+ {
+ responseList = twitter.timelines().getUserTimeline(userID);
+ }
+ else
+ {
+ responseList = twitter.timelines().getUserTimeline(userID, paging);
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e.toString());
+ return new twitter4j.Status[0];
+ }
+ return responseList.toArray(new twitter4j.Status[responseList.size()]);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/util/TwitterUtils.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/util/TwitterUtils.java
new file mode 100644
index 00000000..0c9c4966
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/twitter/util/TwitterUtils.java
@@ -0,0 +1,346 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.twitter.util;
+
+import android.text.TextUtils;
+import com.twitter.Validator;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.DirectMessageCache;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.ShowDirectMessageTask;
+import net.lacolaco.smileessence.twitter.task.ShowStatusTask;
+import net.lacolaco.smileessence.twitter.task.ShowUserTask;
+import twitter4j.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class TwitterUtils
+{
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ /**
+ * Get twitter style fixed text length
+ *
+ * @return length
+ */
+ public static int getFixedTextLength(String str)
+ {
+ Validator validator = new Validator();
+ return validator.getTweetLength(str);
+ }
+
+ /**
+ * Get status from api if not cached
+ */
+ public static void tryGetStatus(Account account, long statusID, final StatusCallback callback)
+ {
+ Status status = StatusCache.getInstance().get(statusID);
+ if(status != null)
+ {
+ callback.success(status);
+ //update cache
+ ShowStatusTask task = new ShowStatusTask(new TwitterApi(account).getTwitter(), statusID);
+ task.execute();
+ }
+ else
+ {
+ ShowStatusTask task = new ShowStatusTask(new TwitterApi(account).getTwitter(), statusID)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status status)
+ {
+ super.onPostExecute(status);
+ if(status != null)
+ {
+ callback.success(status);
+ }
+ else
+ {
+ callback.error();
+ }
+ }
+ };
+ task.execute();
+ }
+ }
+
+ /**
+ * Get status from api if not cached
+ */
+ public static void tryGetUser(Account account, long userID, final UserCallback callback)
+ {
+ User user = UserCache.getInstance().get(userID);
+ if(user != null)
+ {
+ callback.success(user);
+ ShowUserTask task = new ShowUserTask(new TwitterApi(account).getTwitter(), userID);
+ task.execute();
+ }
+ else
+ {
+ ShowUserTask task = new ShowUserTask(new TwitterApi(account).getTwitter(), userID)
+ {
+ @Override
+ protected void onPostExecute(User user)
+ {
+ super.onPostExecute(user);
+ if(user != null)
+ {
+ callback.success(user);
+ }
+ else
+ {
+ callback.error();
+ }
+
+ }
+ };
+ task.execute();
+ }
+ }
+
+ /**
+ * Get direct message from api if not cached
+ */
+ public static void tryGetMessage(Account account, long messageID, final MessageCallback callback)
+ {
+ DirectMessage message = DirectMessageCache.getInstance().get(messageID);
+ if(message != null)
+ {
+ callback.success(message);
+ ShowDirectMessageTask task = new ShowDirectMessageTask(new TwitterApi(account).getTwitter(), messageID);
+ task.execute();
+ }
+ else
+ {
+ ShowDirectMessageTask task = new ShowDirectMessageTask(new TwitterApi(account).getTwitter(), messageID)
+ {
+ @Override
+ protected void onPostExecute(DirectMessage directMessage)
+ {
+ super.onPostExecute(directMessage);
+ if(directMessage != null)
+ {
+ callback.success(directMessage);
+ }
+ else
+ {
+ callback.error();
+ }
+ }
+ };
+ task.execute();
+ }
+ }
+
+ /**
+ * Get array of screenName in own text
+ *
+ * @param status status
+ * @param excludeScreenName
+ * @return
+ */
+ public static Collection<String> getScreenNames(Status status, String excludeScreenName)
+ {
+ ArrayList<String> names = new ArrayList<>();
+ names.add(status.getUser().getScreenName());
+ if(status.getUserMentionEntities() != null)
+ {
+ for(UserMentionEntity entity : status.getUserMentionEntities())
+ {
+ if(names.contains(entity.getScreenName()))
+ {
+ continue;
+ }
+ names.add(entity.getScreenName());
+ }
+ }
+ if(excludeScreenName != null)
+ {
+ names.remove(excludeScreenName);
+ }
+ return names;
+ }
+
+ public static Collection<String> getScreenNames(DirectMessage message, String excludeScreenName)
+ {
+ ArrayList<String> names = new ArrayList<>();
+ names.add(message.getSenderScreenName());
+ if(!message.getRecipientScreenName().equals(message.getSenderScreenName()))
+ {
+ names.add(message.getRecipientScreenName());
+ }
+ if(message.getUserMentionEntities() != null)
+ {
+ for(UserMentionEntity entity : message.getUserMentionEntities())
+ {
+ if(names.contains(entity.getScreenName()))
+ {
+ continue;
+ }
+ names.add(entity.getScreenName());
+ }
+ }
+ if(excludeScreenName != null)
+ {
+ names.remove(excludeScreenName);
+ }
+ return names;
+ }
+
+ public static String getUserHomeURL(String screenName)
+ {
+ return String.format("https://twitter.com/%s", screenName);
+ }
+
+ public static String getAclogTimelineURL(String screenName)
+ {
+ return String.format("http://aclog.koba789.com/%s/timeline", screenName);
+ }
+
+ public static String getFavstarRecentURL(String screenName)
+ {
+ return String.format("http://favstar.fm/users/%s/recent", screenName);
+ }
+
+ public static String getTwilogURL(String screenName)
+ {
+ return String.format("http://twilog.org/%s", screenName);
+ }
+
+ /**
+ * Get twitter status permalink
+ *
+ * @param status status
+ * @return url string
+ */
+ public static String getStatusURL(Status status)
+ {
+ return String.format("https://twitter.com/%s/status/%s", getOriginalStatus(status).getUser().getScreenName(), getOriginalStatus(status).getId());
+ }
+
+ /**
+ * Get "@screen_name: text" format text
+ *
+ * @param status status
+ * @return summary string
+ */
+ public static String getStatusSummary(Status status)
+ {
+ return String.format("@%s: %s", status.getUser().getScreenName(), status.getText());
+ }
+
+ /**
+ * Replace urls by entities
+ *
+ * @param text raw text
+ * @param entities url entities
+ * @param expand if true, use expanded url
+ * @return replaced text
+ */
+ public static String replaceURLEntities(String text, URLEntity[] entities, boolean expand)
+ {
+ if(TextUtils.isEmpty(text))
+ {
+ return "";
+ }
+ else if(entities == null)
+ {
+ return text;
+ }
+ if(entities.length == 0)
+ {
+ return text;
+ }
+ for(URLEntity entity : entities)
+ {
+ text = text.replace(entity.getURL(), expand ? entity.getExpandedURL() : entity.getDisplayURL());
+ }
+ return text;
+ }
+
+ /**
+ * Return original status text. If status is not retweet, value is same to a given.
+ *
+ * @param status
+ * @return
+ */
+ public static String getOriginalStatusText(Status status)
+ {
+ return status.isRetweet() ? status.getRetweetedStatus().getText() : status.getText();
+ }
+
+ public static Paging getPaging(int count)
+ {
+ return new Paging(1).count(count);
+ }
+
+ public static int getPagingCount(MainActivity activity)
+ {
+ return activity.getUserPreferenceHelper().getValue(R.string.key_setting_timelines, 20);
+ }
+
+ public static Status getOriginalStatus(Status status)
+ {
+ return StatusCache.getInstance().get((status.isRetweet() ? status.getRetweetedStatus() : status).getId());
+ }
+
+ public static String getMessageSummary(DirectMessage message)
+ {
+ return String.format("@%s: %s", message.getSender().getScreenName(), message.getText());
+ }
+
+ // -------------------------- INNER CLASSES --------------------------
+
+ public interface StatusCallback
+ {
+
+ void success(Status status);
+
+ void error();
+ }
+
+ public interface UserCallback
+ {
+
+ void success(User user);
+
+ void error();
+ }
+
+ public interface MessageCallback
+ {
+
+ void success(DirectMessage message);
+
+ void error();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapOptimizer.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapOptimizer.java
new file mode 100644
index 00000000..6971f48e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapOptimizer.java
@@ -0,0 +1,144 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.media.ExifInterface;
+import android.os.Environment;
+import net.lacolaco.smileessence.logging.Logger;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class BitmapOptimizer
+{
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static String rotateImageByExif(Activity activity, String filePath)
+ {
+ filePath = filePath.replace("file://", "");
+ int degree = getRotateDegreeFromExif(filePath);
+ if(degree > 0)
+ {
+ OutputStream out = null;
+ Bitmap bitmap = null;
+ Bitmap rotatedImage = null;
+ try
+ {
+ Matrix mat = new Matrix();
+ mat.postRotate(degree);
+ BitmapFactory.Options opt = new BitmapFactory.Options();
+ opt.inJustDecodeBounds = true;
+ BitmapFactory.decodeFile(filePath, opt);
+ int width = 480;
+ int scale = 1;
+ if(opt.outWidth > width)
+ {
+ scale = opt.outWidth / width + 2;
+ }
+ opt.inJustDecodeBounds = false;
+ opt.inSampleSize = scale;
+ bitmap = BitmapFactory.decodeFile(filePath, opt);
+ rotatedImage = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mat, true);
+ File file = new File(filePath);
+ String outPath = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/" + file.getName();
+ Logger.debug(outPath);
+ out = new FileOutputStream(outPath);
+ rotatedImage.compress(Bitmap.CompressFormat.JPEG, 100, out);
+ return outPath;
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ Logger.error(e);
+ }
+ finally
+ {
+ if(out != null)
+ {
+ try
+ {
+ out.close();
+ }
+ catch(IOException e)
+ {
+ e.printStackTrace();
+ Logger.error(e);
+ }
+ }
+ if(bitmap != null)
+ {
+ bitmap.recycle();
+ }
+ if(rotatedImage != null)
+ {
+ rotatedImage.recycle();
+ }
+ }
+ }
+ return filePath;
+ }
+
+ private static int getRotateDegreeFromExif(String filePath)
+ {
+ int degree = 0;
+ try
+ {
+ ExifInterface exifInterface = new ExifInterface(filePath);
+ int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
+ if(orientation == ExifInterface.ORIENTATION_ROTATE_90)
+ {
+ degree = 90;
+ }
+ else if(orientation == ExifInterface.ORIENTATION_ROTATE_180)
+ {
+ degree = 180;
+ }
+ else if(orientation == ExifInterface.ORIENTATION_ROTATE_270)
+ {
+ degree = 270;
+ }
+ if(degree != 0)
+ {
+ exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, "0");
+ exifInterface.saveAttributes();
+ }
+ }
+ catch(IOException e)
+ {
+ degree = -1;
+ e.printStackTrace();
+ Logger.error(e);
+ }
+ Logger.debug("Exif degree = " + degree);
+ return degree;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapThumbnailTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapThumbnailTask.java
new file mode 100644
index 00000000..8416651a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapThumbnailTask.java
@@ -0,0 +1,80 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.ThumbnailUtils;
+import android.os.AsyncTask;
+import android.widget.ImageView;
+
+public class BitmapThumbnailTask extends AsyncTask<Void, Void, Bitmap>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Activity activity;
+ private final String filePath;
+ private final ImageView imageView;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public BitmapThumbnailTask(Activity activity, String filePath, ImageView imageView)
+ {
+ this.activity = activity;
+ this.filePath = filePath;
+ this.imageView = imageView;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap)
+ {
+ if(bitmap != null && imageView != null)
+ {
+ imageView.setImageBitmap(bitmap);
+ }
+ }
+
+ @Override
+ protected Bitmap doInBackground(Void... params)
+ {
+ BitmapFactory.Options opt = new BitmapFactory.Options();
+ opt.inPurgeable = true; // GC可能にする
+ opt.inSampleSize = 2;
+ // ContentResolver resolver = activity.getContentResolver();
+ // Cursor cursor = resolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.ImageColumns.DATA + " = ?", new String[]{filePath}, null);
+ // if(cursor.moveToFirst())
+ // {
+ // // サムネイルの取得
+ // long id = cursor.getLong(cursor.getColumnIndex("_id"));
+ // return MediaStore.Images.Thumbnails.getThumbnail(resolver, id, MediaStore.Images.Thumbnails.MICRO_KIND, opt);
+ // }
+ // return null;
+ return ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(filePath), 100, 100, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapURLTask.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapURLTask.java
new file mode 100644
index 00000000..b9563c36
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/BitmapURLTask.java
@@ -0,0 +1,91 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.widget.ImageView;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+public class BitmapURLTask extends AsyncTask<Void, Void, Bitmap>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String url;
+ private final ImageView imageView;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public BitmapURLTask(String url, ImageView imageView)
+ {
+ this.url = url;
+ this.imageView = imageView;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap)
+ {
+ if(imageView != null)
+ {
+ imageView.setImageBitmap(bitmap);
+ }
+ }
+
+ @Override
+ protected Bitmap doInBackground(Void... params)
+ {
+ InputStream inputStream = null;
+ try
+ {
+ inputStream = new URL(url).openStream();
+ BitmapFactory.Options opt = new BitmapFactory.Options();
+ opt.inPurgeable = true; // GC可能にする
+ return BitmapFactory.decodeStream(inputStream, null, opt);
+ }
+ catch(IOException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ finally
+ {
+ try
+ {
+ inputStream.close();
+ }
+ catch(IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/IntentUtils.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/IntentUtils.java
new file mode 100644
index 00000000..ac4fb4b6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/IntentUtils.java
@@ -0,0 +1,98 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+
+import java.util.List;
+
+public class IntentUtils
+{
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ /**
+ * Start activity if callable apps are found
+ *
+ * @param activity
+ * @param intent
+ * @return
+ */
+ public static boolean startActivityIfFound(Activity activity, Intent intent)
+ {
+ if(canStartActivity(activity, intent))
+ {
+ activity.startActivity(intent);
+ return true;
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_error_start_activity, NotificationType.ALERT).publish();
+ }
+ return false;
+ }
+
+ /**
+ * Check intent has any callable activity
+ *
+ * @param activity
+ * @param intent
+ * @return
+ */
+ public static boolean canStartActivity(Activity activity, Intent intent)
+ {
+ PackageManager packageManager = activity.getPackageManager();
+ List<ResolveInfo> infos = packageManager.queryIntentActivities(intent, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
+ return !infos.isEmpty();
+ }
+
+ /**
+ * Start activity for result if callable apps are found
+ *
+ * @param activity
+ * @param intent
+ * @param requestCode
+ * @return
+ */
+ public static boolean startActivityForResultIfFound(Activity activity, Intent intent, int requestCode)
+ {
+ if(canStartActivity(activity, intent))
+ {
+ activity.startActivityForResult(intent, requestCode);
+ return true;
+ }
+ else
+ {
+ new Notificator(activity, R.string.notice_error_start_activity, NotificationType.ALERT).publish();
+ }
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/Morse.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/Morse.java
new file mode 100644
index 00000000..bbcee557
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/Morse.java
@@ -0,0 +1,156 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Morse
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static HashMap<String, String> jaMc;
+ private static HashMap<String, String> mcJa;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ /**
+ * 与えられた文字列がモールス文を含むかどうかを返す
+ *
+ * @param mc 判定する文字列
+ * @return モールスを含むならtrue, そうでなければfalse
+ */
+ public static boolean isMorse(String mc)
+ {
+ Pattern pattern = Pattern.compile("[-・]+");
+ Matcher matcher = pattern.matcher(mc);
+ ArrayList<String> list = new ArrayList<String>();
+ while(matcher.find())
+ {
+ list.add(matcher.group());
+ }
+ if(list.size() <= 2)
+ {
+ return false;
+ }
+ else
+ {
+ for(String s : list)
+ {
+ if(!s.equals("・・・") && !s.equals("・・") && !s.equals("・"))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * 和文モールスをカタカナ・数字に復元する *
+ *
+ * @param str 復元したい文字列
+ * @return 復元部分が置換された文字列
+ */
+ public static String morseToJa(String str)
+ {
+ String[] strArr = toRightMorse(str).split(" ");
+ StringBuilder sb = new StringBuilder();
+ for(String tok : strArr)
+ {
+ sb.append(mcJa.containsKey(tok) ? mcJa.get(tok) : tok);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * ひらがな・カタカナ・数字をモールス文に変換する
+ *
+ * @param str 変換したい文字列
+ * @return 変換部分が置換された文字列
+ */
+ public static String jaToMorse(String str)
+ {
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i < str.length(); i++)
+ {
+ String tok = String.valueOf(str.charAt(i));
+ if(jaMc.containsKey(tok))
+ {
+ sb.append(jaMc.get(tok));
+ sb.append(" ");
+ }
+ else
+ {
+ sb.append(tok);
+ }
+ }
+ return sb.toString();
+ }
+
+ private static String toRightMorse(String str)
+ {
+ str = str.replace("‐", "-").replace(" ", " ").trim();
+ Pattern pattern = Pattern.compile("[^・- ][・-]");
+ StringBuilder sb = new StringBuilder(str);
+ Matcher matcher = pattern.matcher(str);
+ while(matcher.find())
+ {
+ int i = matcher.start();
+ sb.insert(i + 1, " ");
+ matcher.reset(sb);
+ }
+ pattern = Pattern.compile("[・-][^・- ]");
+ matcher = pattern.matcher(sb);
+ while(matcher.find())
+ {
+ int i = matcher.start();
+ sb.insert(i + 1, " ");
+ matcher.reset(sb);
+ }
+ return sb.toString();
+ }
+
+ static
+ {
+ jaMc = new HashMap<String, String>();
+ mcJa = new HashMap<String, String>();
+
+ String[][] ja2 = {{"・-", "イ"}, {"・-・-", "ロ"}, {"-・・・", "ハ"}, {"-・-・", "ニ"}, {"-・・", "ホ"}, {"・", "ヘ"}, {"・・-・・", "ト"}, {"・・-・", "チ"}, {"--・", "リ"}, {"・・・・", "ヌ"}, {"-・--・", "ル"}, {"・---", "ヲ"}, {"-・-", "ワ"}, {"・-・・", "カ"}, {"--", "ヨ"}, {"-・", "タ"}, {"---", "レ"}, {"---・", "ソ"}, {"・--・", "ツ"}, {"--・-", "ネ"}, {"・-・", "ナ"}, {"・・・", "ラ"}, {"-", "ム"}, {"・・-", "ウ"}, {"・-・・-", "ヰ"}, {"・・--", "ノ"}, {"・-・・・", "オ"}, {"・・・-", "ク"}, {"・--", "ヤ"}, {"-・・-", "マ"}, {"-・--", "ケ"}, {"--・・", "フ"}, {"----", "コ"}, {"-・---", "エ"}, {"・-・--", "テ"}, {"--・--", "ア"}, {"-・-・-", "サ"}, {"-・-・・", "キ"}, {"-・・--", "ユ"}, {"-・・・-", "メ"}, {"・・-・-", "ミ"}, {"--・-・", "シ"}, {"・--・・", "ヱ"}, {"--・・-", "ヒ"}, {"-・・-・", "モ"}, {"・---・", "セ"}, {"---・-", "ス"}, {"・-・-・", "ン"}, {"・・", "゛"}, {"・・--・", "゜"}, {"・--・-", "ー"}, {"・-・-・-", "、"}, {"-・--・-", "("}, {"・-・・-・", ")"}, {"・----", "1"}, {"・・---", "2"}, {"・・・--", "3"}, {"・・・・-", "4"}, {"・・・・・", "5"}, {"-・・・・", "6"}, {"--・・・", "7"}, {"---・・", "8"}, {"----・", "9"}, {"-----", "0"}, {"", ""}};
+ for(String[] pr : ja2)
+ {
+ mcJa.put(pr[0], pr[1]);
+ jaMc.put(pr[1], pr[0]);
+ }
+
+ String[][] ja1 = {{"い", "・-"}, {"ィ", "・-"}, {"ぃ", "・-"}, {"ろ", "・-・-"}, {"は", "-・・・"}, {"に", "-・-・"}, {"ほ", "-・・"}, {"へ", "・"}, {"と", "・・-・・"}, {"ち", "・・-・"}, {"り", "--・"}, {"ぬ", "・・・・"}, {"る", "-・--・"}, {"を", "・---"}, {"わ", "-・-"}, {"ヮ", "-・-"}, {"ゎ", "-・-"}, {"か", "・-・・"}, {"ヵ", "・-・・"}, {"よ", "--"}, {"ョ", "--"}, {"ょ", "--"}, {"た", "-・"}, {"れ", "---"}, {"そ", "---・"}, {"つ", "・--・"}, {"ッ", "・--・"}, {"っ", "・--・"}, {"ね", "--・-"}, {"な", "・-・"}, {"ら", "・・・"}, {"む", "-"}, {"う", "・・-"}, {"ゥ", "・・-"}, {"ぅ", "・・-"}, {"ゐ", "・-・・-"}, {"の", "・・--"}, {"お", "・-・・・"}, {"ォ", "・-・・・"}, {"ぉ", "・-・・・"}, {"く", "・・・-"}, {"や", "・--"}, {"ャ", "・--"}, {"ゃ", "・--"}, {"ま", "-・・-"}, {"け", "-・--"}, {"ヶ", "-・--"}, {"ふ", "--・・"}, {"こ", "----"}, {"え", "-・---"}, {"ェ", "-・---"}, {"ぇ", "-・---"}, {"て", "・-・--"}, {"あ", "--・--"}, {"ァ", "--・--"}, {"ぁ", "--・--"}, {"さ", "-・-・-"}, {"き", "-・-・・"}, {"ゆ", "-・・--"}, {"ュ", "-・・--"}, {"ゅ", "-・・--"}, {"め", "-・・・-"}, {"み", "・・-・-"}, {"し", "--・-・"}, {"ゑ", "・--・・"}, {"ひ", "--・・-"}, {"も", "-・・-・"}, {"せ", "・---・"}, {"す", "---・-"}, {"ん", "・-・-・"}, {"ガ", "・-・・ ・・"}, {"が", "・-・・ ・・"}, {"ギ", "-・-・・ ・・"}, {"ぎ", "-・-・・ ・・"}, {"グ", "・・・- ・・"}, {"ぐ", "・・・- ・・"}, {"ゲ", "-・-- ・・"}, {"げ", "-・-- ・・"}, {"ゴ", "---- ・・"}, {"ご", "---- ・・"}, {"ザ", "-・-・- ・・"}, {"ざ", "-・-・- ・・"}, {"ジ", "--・-・ ・・"}, {"じ", "--・-・ ・・"}, {"ズ", "---・- ・・"}, {"ず", "---・- ・・"}, {"ゼ", "・---・ ・・"}, {"ぜ", "・---・ ・・"}, {"ゾ", "---・ ・・"}, {"ぞ", "---・ ・・"}, {"ダ", "-・ ・・"}, {"だ", "-・ ・・"}, {"ヂ", "・・-・ ・・"}, {"ぢ", "・・-・ ・・"}, {"ヅ", "・--・ ・・"}, {"づ", "・--・ ・・"}, {"デ", "・-・-- ・・"}, {"で", "・-・-- ・・"}, {"ド", "・・-・・ ・・"}, {"ど", "・・-・・ ・・"}, {"バ", "-・・・ ・・"}, {"ば", "-・・・ ・・"}, {"ビ", "--・・- ・・"}, {"び", "--・・- ・・"}, {"ブ", "--・・ ・・"}, {"ぶ", "--・・ ・・"}, {"ベ", "・ ・・"}, {"べ", "・ ・・"}, {"ボ", "-・・ ・・"}, {"ぼ", "-・・ ・・"}, {"パ", "-・・・ ・・--・"}, {"ぱ", "-・・・ ・・--・"}, {"ピ", "--・・- ・・--・"}, {"ぴ", "--・・- ・・--・"}, {"プ", "--・・ ・・--・"}, {"ぷ", "--・・ ・・--・"}, {"ペ", "・ ・・--・"}, {"ぺ", "・ ・・--・"}, {"ポ", "-・・ ・・--・"}, {"ぽ", "-・・ ・・--・"}, {"ヴ", "・・- ・・"}};
+ for(String[] to : ja1)
+ jaMc.put(to[0], to[1]);
+ }
+
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/NameStyles.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/NameStyles.java
new file mode 100644
index 00000000..8506c3cc
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/NameStyles.java
@@ -0,0 +1,54 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+public class NameStyles
+{
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static String getNameString(int style, String screenName, String name)
+ {
+ switch(style)
+ {
+ case 1:
+ {
+ return String.format("%s / %s", name, screenName);
+ }
+ case 2:
+ {
+ return String.format("%s", screenName);
+ }
+ case 3:
+ {
+ return String.format("%s", name);
+ }
+ default:
+ {
+ return String.format("%s / %s", screenName, name);
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/NetworkHelper.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/NetworkHelper.java
new file mode 100644
index 00000000..0836417e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/NetworkHelper.java
@@ -0,0 +1,53 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+public class NetworkHelper
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Context context;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public NetworkHelper(Context context)
+ {
+ this.context = context;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public boolean canConnect()
+ {
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo info = cm.getActiveNetworkInfo();
+ return info != null && info.isConnected();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/StringUtils.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/StringUtils.java
new file mode 100644
index 00000000..dcb15aee
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/StringUtils.java
@@ -0,0 +1,63 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import java.util.Calendar;
+import java.util.Date;
+
+public class StringUtils
+{
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static String dateToString(Date date)
+ {
+ Calendar cal = Calendar.getInstance();
+ Calendar calToday = Calendar.getInstance();
+
+ cal.setTime(date);
+
+ int y = cal.get(Calendar.YEAR);
+ int m = cal.get(Calendar.MONTH);
+ int d = cal.get(Calendar.DATE);
+ int h = cal.get(Calendar.HOUR_OF_DAY);
+ int min = cal.get(Calendar.MINUTE);
+ int s = cal.get(Calendar.SECOND);
+
+ StringBuilder builder = new StringBuilder();
+
+ if(cal.get(Calendar.YEAR) != calToday.get(Calendar.YEAR))
+ {
+ builder.append(y).append("/");
+ }
+ if(cal.get(Calendar.DAY_OF_YEAR) != calToday.get(Calendar.DAY_OF_YEAR))
+ {
+ builder.append(String.format("%02d", m + 1)).append("/").append(String.format("%02d", d)).append(" ");
+ }
+ builder.append(String.format("%02d", h)).append(":").append(String.format("%02d", min)).append(":").append(String.format("%02d", s));
+
+ return builder.toString();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/Themes.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/Themes.java
new file mode 100644
index 00000000..07458b7f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/Themes.java
@@ -0,0 +1,82 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.logging.Logger;
+
+public class Themes
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final int THEME_DARK = 0;
+ public static final int THEME_LIGHT = 1;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static int getTheme(int index)
+ {
+ switch(index)
+ {
+ case THEME_DARK:
+ {
+ Logger.debug("Theme:Dark");
+ return R.style.theme_dark;
+ }
+ case THEME_LIGHT:
+ {
+ Logger.debug("Theme:Light");
+ return R.style.theme_light;
+ }
+ default:
+ {
+ Logger.debug("Theme:Default");
+ return R.style.theme_dark;
+ }
+ }
+ }
+
+ public static int getStyledColor(Context context, int theme, int attribute, int defaultColor)
+ {
+ int styleResID = theme == THEME_LIGHT ? R.style.theme_light : R.style.theme_dark;
+ TypedArray array = context.obtainStyledAttributes(styleResID, new int[]{attribute});
+ int color = array.getColor(0, defaultColor);
+ array.recycle();
+ return color;
+ }
+
+ public static Drawable getStyledDrawable(Context context, int theme, int attribute)
+ {
+ int styleResID = theme == THEME_LIGHT ? R.style.theme_light : R.style.theme_dark;
+ TypedArray array = context.obtainStyledAttributes(styleResID, new int[]{attribute});
+ Drawable drawable = array.getDrawable(0);
+ array.recycle();
+ return drawable;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/util/UIHandler.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/UIHandler.java
new file mode 100644
index 00000000..1688c622
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/util/UIHandler.java
@@ -0,0 +1,79 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.util;
+
+import android.os.Handler;
+import android.os.Looper;
+
+public abstract class UIHandler extends Handler implements Runnable
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UIHandler()
+ {
+ super(Looper.getMainLooper());
+ }
+
+ public UIHandler(Handler.Callback callback)
+ {
+ super(Looper.getMainLooper(), callback);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface Runnable ---------------------
+
+ @Override
+ public abstract void run();
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public boolean post()
+ {
+ return post(this);
+ }
+
+ public boolean postAtFrontOfQueue()
+ {
+ return postAtFrontOfQueue(this);
+ }
+
+ public boolean postAtTime(long uptimeMillis)
+ {
+ return postAtTime(this, uptimeMillis);
+ }
+
+ public boolean postAtTime(Object token, long uptimeMillis)
+ {
+ return postAtTime(this, token, uptimeMillis);
+ }
+
+ public boolean postDelayed(long delayMillis)
+ {
+ return postDelayed(this, delayMillis);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/CustomListFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/CustomListFragment.java
new file mode 100644
index 00000000..d4535f2c
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/CustomListFragment.java
@@ -0,0 +1,189 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import com.handmark.pulltorefresh.library.PullToRefreshBase;
+import com.handmark.pulltorefresh.library.PullToRefreshListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+
+public class CustomListFragment extends Fragment implements AbsListView.OnScrollListener,
+ PullToRefreshBase.OnRefreshListener2<ListView>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String ADAPTER_INDEX = "fragmentIndex";
+ public static final int SCROLL_DURATION = 1500;
+
+ private int fragmentIndex;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ protected PullToRefreshBase.Mode getRefreshMode()
+ {
+ return PullToRefreshBase.Mode.DISABLED;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ @Override
+ public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView)
+ {
+
+ }
+
+ @Override
+ public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView)
+ {
+
+ }
+
+ // --------------------- Interface OnScrollListener ---------------------
+
+ @Override
+ public void onScrollStateChanged(AbsListView absListView, int scrollState)
+ {
+ Bundle args = getArguments();
+ fragmentIndex = args.getInt(ADAPTER_INDEX);
+ CustomListAdapter<?> adapter = getListAdapter(fragmentIndex);
+ adapter.setNotifiable(false);
+
+ if(absListView.getFirstVisiblePosition() == 0 && absListView.getChildAt(0) != null && absListView.getChildAt(0).getTop() == 0)
+ {
+ if(scrollState == SCROLL_STATE_IDLE)
+ {
+ updateListViewWithNotice(absListView, adapter, true);
+ }
+ }
+ }
+
+ @Override
+ public void onScroll(AbsListView absListView, int i, int i2, int i3)
+ {
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ fragmentIndex = args.getInt(ADAPTER_INDEX);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View page = inflater.inflate(R.layout.fragment_list, container, false);
+ Bundle args = getArguments();
+ int fragmentIndex = args.getInt(ADAPTER_INDEX);
+ PullToRefreshListView listView = getListView(page);
+ ListAdapter adapter = getListAdapter(fragmentIndex);
+ listView.setAdapter(adapter);
+ listView.setOnScrollListener(this);
+ listView.setOnRefreshListener(this);
+ listView.setMode(getRefreshMode());
+ return page;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState)
+ {
+ super.onSaveInstanceState(outState);
+ outState.putInt(ADAPTER_INDEX, fragmentIndex);
+ }
+
+ @Override
+ public void onViewStateRestored(Bundle savedInstanceState)
+ {
+ super.onViewStateRestored(savedInstanceState);
+ if(savedInstanceState != null)
+ {
+ fragmentIndex = savedInstanceState.getInt(ADAPTER_INDEX);
+ }
+ }
+
+ protected CustomListAdapter<?> getListAdapter(int fragmentIndex)
+ {
+ return ((MainActivity) getActivity()).getListAdapter(fragmentIndex);
+ }
+
+ protected PullToRefreshListView getListView(View page)
+ {
+ return (PullToRefreshListView) page.findViewById(R.id.fragment_list_listview);
+ }
+
+ protected void notifyListUpdated(int increments)
+ {
+ Notificator.publish(getActivity(), getString(R.string.notice_timeline_new, increments));
+ }
+
+ protected void updateListViewWithNotice(AbsListView absListView, CustomListAdapter<?> adapter, boolean addedToTop)
+ {
+ int before = adapter.getCount();
+ adapter.notifyDataSetChanged(); // synchronized call (not adapter#updateForce())
+ int after = adapter.getCount();
+ int increments = after - before;
+ if(increments > 0)
+ {
+ adapter.setNotifiable(false);
+ notifyListUpdated(increments);
+ if(addedToTop)
+ {
+ absListView.setSelection(increments + 1);
+ absListView.smoothScrollToPositionFromTop(increments, 0);
+ absListView.setSelection(increments);
+ }
+ else
+ {
+ absListView.smoothScrollToPositionFromTop(before, 0);
+ }
+
+ if(increments == 1)
+ {
+ adapter.setNotifiable(true);
+ }
+ }
+ else
+ {
+ adapter.setNotifiable(true);
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/HistoryFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/HistoryFragment.java
new file mode 100644
index 00000000..64965176
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/HistoryFragment.java
@@ -0,0 +1,58 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.widget.ListView;
+import com.handmark.pulltorefresh.library.PullToRefreshBase;
+
+/**
+ * Fragment for notice history
+ */
+public class HistoryFragment extends CustomListFragment
+{
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ protected PullToRefreshBase.Mode getRefreshMode()
+ {
+ return PullToRefreshBase.Mode.DISABLED;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ @Override
+ public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView)
+ {
+ }
+
+ @Override
+ public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView)
+ {
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/HomeFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/HomeFragment.java
new file mode 100644
index 00000000..d3cdabc8
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/HomeFragment.java
@@ -0,0 +1,136 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.widget.ListView;
+import com.handmark.pulltorefresh.library.PullToRefreshBase;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.StatusFilter;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.HomeTimelineTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.UIHandler;
+import net.lacolaco.smileessence.view.adapter.StatusListAdapter;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.Paging;
+import twitter4j.Twitter;
+
+public class HomeFragment extends CustomListFragment
+{
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ protected PullToRefreshBase.Mode getRefreshMode()
+ {
+ return PullToRefreshBase.Mode.BOTH;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ @Override
+ public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ if(activity.isStreaming())
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ StatusListAdapter adapter = getListAdapter(activity);
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, true);
+ refreshView.onRefreshComplete();
+ }
+ }.post();
+ return;
+ }
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final StatusListAdapter adapter = getListAdapter(activity);
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setSinceId(adapter.getTopID());
+ }
+ new HomeTimelineTask(twitter, activity, paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(int i = statuses.length - 1; i >= 0; i--)
+ {
+ twitter4j.Status status = statuses[i];
+ StatusViewModel viewModel = new StatusViewModel(status, currentAccount);
+ adapter.addToTop(viewModel);
+ StatusFilter.filter(activity, viewModel);
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, true);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final StatusListAdapter adapter = getListAdapter(activity);
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setMaxId(adapter.getLastID() - 1);
+ }
+ new HomeTimelineTask(twitter, activity, paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(twitter4j.Status status : statuses)
+ {
+ StatusViewModel viewModel = new StatusViewModel(status, currentAccount);
+ adapter.addToBottom(viewModel);
+ StatusFilter.filter(activity, viewModel);
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, false);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ private StatusListAdapter getListAdapter(MainActivity activity)
+ {
+ return (StatusListAdapter) activity.getListAdapter(MainActivity.ADAPTER_HOME);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/MentionsFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/MentionsFragment.java
new file mode 100644
index 00000000..31a4c006
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/MentionsFragment.java
@@ -0,0 +1,116 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.widget.ListView;
+import com.handmark.pulltorefresh.library.PullToRefreshBase;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.MentionsTimelineTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.StatusListAdapter;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.Paging;
+import twitter4j.Twitter;
+
+public class MentionsFragment extends CustomListFragment
+{
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ protected PullToRefreshBase.Mode getRefreshMode()
+ {
+ return PullToRefreshBase.Mode.BOTH;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ @Override
+ public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final StatusListAdapter adapter = getListAdapter(activity);
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setSinceId(adapter.getTopID());
+ }
+ new MentionsTimelineTask(twitter, activity, paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(int i = statuses.length - 1; i >= 0; i--)
+ {
+ twitter4j.Status status = statuses[i];
+ adapter.addToTop(new StatusViewModel(status, currentAccount));
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, true);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final StatusListAdapter adapter = getListAdapter(activity);
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setMaxId(adapter.getLastID() - 1);
+ }
+ new MentionsTimelineTask(twitter, activity, paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(twitter4j.Status status : statuses)
+ {
+ adapter.addToBottom(new StatusViewModel(status, currentAccount));
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, false);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ private StatusListAdapter getListAdapter(MainActivity activity)
+ {
+ return (StatusListAdapter) activity.getListAdapter(MainActivity.ADAPTER_MENTIONS);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/MessagesFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/MessagesFragment.java
new file mode 100644
index 00000000..430c29a0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/MessagesFragment.java
@@ -0,0 +1,119 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.widget.ListView;
+import com.handmark.pulltorefresh.library.PullToRefreshBase;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.DirectMessagesTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.MessageListAdapter;
+import net.lacolaco.smileessence.viewmodel.MessageViewModel;
+import twitter4j.DirectMessage;
+import twitter4j.Paging;
+import twitter4j.Twitter;
+
+/**
+ * Fragment of messages list
+ */
+public class MessagesFragment extends CustomListFragment
+{
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ protected PullToRefreshBase.Mode getRefreshMode()
+ {
+ return PullToRefreshBase.Mode.BOTH;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ @Override
+ public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final MessageListAdapter adapter = getListAdapter(activity);
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setSinceId(adapter.getTopID());
+ }
+ new DirectMessagesTask(twitter, activity, paging)
+ {
+ @Override
+ protected void onPostExecute(DirectMessage[] directMessages)
+ {
+ super.onPostExecute(directMessages);
+ for(int i = directMessages.length - 1; i >= 0; i--)
+ {
+ adapter.addToTop(new MessageViewModel(directMessages[i], currentAccount));
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, true);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final MessageListAdapter adapter = getListAdapter(activity);
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setMaxId(adapter.getLastID() - 1);
+ }
+ new DirectMessagesTask(twitter, activity, paging)
+ {
+ @Override
+ protected void onPostExecute(DirectMessage[] directMessages)
+ {
+ super.onPostExecute(directMessages);
+ for(DirectMessage directMessage : directMessages)
+ {
+ adapter.addToBottom(new MessageViewModel(directMessage, currentAccount));
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, false);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ private MessageListAdapter getListAdapter(MainActivity activity)
+ {
+ return (MessageListAdapter) activity.getListAdapter(MainActivity.ADAPTER_MESSAGES);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/PostFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/PostFragment.java
new file mode 100644
index 00000000..f0636fe0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/PostFragment.java
@@ -0,0 +1,449 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.method.ArrowKeyMovementMethod;
+import android.view.*;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.*;
+import com.twitter.Validator;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.TweetTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.BitmapThumbnailTask;
+import net.lacolaco.smileessence.util.IntentUtils;
+import net.lacolaco.smileessence.util.UIHandler;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.PostMenuDialogFragment;
+import net.lacolaco.smileessence.view.dialog.SelectImageDialogFragment;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.Status;
+import twitter4j.StatusUpdate;
+
+import java.io.File;
+
+public class PostFragment extends Fragment implements TextWatcher, View.OnFocusChangeListener, View.OnClickListener,
+ PostState.OnPostStateChangeListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private EditText editText;
+ private TextView textViewCount;
+ private Button buttonTweet;
+ private ViewGroup viewGroupReply;
+ private ViewGroup viewGroupMedia;
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(View v)
+ {
+ switch(v.getId())
+ {
+ case R.id.button_post_delete:
+ {
+ deletePost();
+ break;
+ }
+ case R.id.button_post_media:
+ {
+ setImage();
+ break;
+ }
+ case R.id.button_post_menu:
+ {
+ openPostMenu();
+ break;
+ }
+ case R.id.button_post_tweet:
+ {
+ submitPost();
+ break;
+ }
+ case R.id.button_post_reply_delete:
+ {
+ deleteReply();
+ break;
+ }
+ case R.id.button_post_media_delete:
+ {
+ removeImage();
+ break;
+ }
+ case R.id.image_post_media:
+ {
+ displayImage();
+ break;
+ }
+ }
+ }
+
+ // --------------------- Interface OnFocusChangeListener ---------------------
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus)
+ {
+ if(hasFocus)
+ {
+ showIME();
+ }
+ else
+ {
+ hideIME();
+ }
+ }
+
+ // --------------------- Interface OnPostStateChangeListener ---------------------
+
+
+ @Override
+ public void onPostStateChange(final PostState postState)
+ {
+ Logger.debug("PostFragment PostStateChange");
+ final MainActivity activity = (MainActivity) getActivity();
+ if(editText != null)
+ {
+ final int start = postState.getSelectionStart();
+ final int end = postState.getSelectionEnd();
+ editText.removeTextChangedListener(this);
+ editText.setTextKeepState(postState.getText());
+ editText.addTextChangedListener(this);
+ updateTextCount(editText.getText());
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ editText.setSelection(start, end);
+ }
+ }.postAtFrontOfQueue();
+ }
+ if(viewGroupReply != null)
+ {
+ if(postState.getInReplyToStatusID() >= 0)
+ {
+ viewGroupReply.setVisibility(View.VISIBLE);
+ final Account account = activity.getCurrentAccount();
+ TwitterUtils.tryGetStatus(account, postState.getInReplyToStatusID(), new TwitterUtils.StatusCallback()
+ {
+ @Override
+ public void success(Status status)
+ {
+ View header = viewGroupReply.findViewById(R.id.layout_post_reply_status);
+ header = new StatusViewModel(status, account).getView(activity, activity.getLayoutInflater(), header);
+ header.setBackgroundColor(getResources().getColor(R.color.transparent));
+ header.setClickable(false);
+ }
+
+ @Override
+ public void error()
+ {
+ viewGroupReply.setVisibility(View.GONE);
+ }
+ });
+ ImageButton imageButtonDeleteReply = (ImageButton) viewGroupReply.findViewById(R.id.button_post_reply_delete);
+ imageButtonDeleteReply.setOnClickListener(this);
+ }
+ else
+ {
+ viewGroupReply.setVisibility(View.GONE);
+ }
+ }
+ if(viewGroupMedia != null)
+ {
+ ImageView imageViewMedia = (ImageView) viewGroupMedia.findViewById(R.id.image_post_media);
+ if(TextUtils.isEmpty(postState.getMediaFilePath()))
+ {
+ viewGroupMedia.setVisibility(View.GONE);
+ }
+ else
+ {
+ viewGroupMedia.setVisibility(View.VISIBLE);
+
+ }
+ new BitmapThumbnailTask(activity, postState.getMediaFilePath(), imageViewMedia).execute();
+ }
+ }
+
+ // --------------------- Interface TextWatcher ---------------------
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after)
+ {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count)
+ {
+ updateTextCount(s);
+ }
+
+ public void updateTextCount(CharSequence s)
+ {
+ int remainingCount = 140 - TwitterUtils.getFixedTextLength(s.toString());
+ if(!TextUtils.isEmpty(PostState.getState().getMediaFilePath()))
+ {
+ remainingCount -= new Validator().getShortUrlLength();
+ }
+ textViewCount.setText(String.valueOf(remainingCount));
+ if(remainingCount == 140)
+ {
+ textViewCount.setTextColor(getResources().getColor(R.color.red));
+ buttonTweet.setEnabled(false);
+ }
+ else if(remainingCount < 0)
+ {
+ textViewCount.setTextColor(getResources().getColor(R.color.red));
+ buttonTweet.setEnabled(false);
+ }
+ else
+ {
+ textViewCount.setTextAppearance(getActivity(), android.R.style.TextAppearance_Widget_TextView);
+ buttonTweet.setEnabled(true);
+ }
+ setStateFromView();
+ }
+
+ @Override
+ public void afterTextChanged(Editable s)
+ {
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ Logger.debug("PostFragment Create");
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
+ {
+ super.onCreateOptionsMenu(menu, inflater);
+ menu.removeItem(R.id.actionbar_post);
+ showIME();
+ }
+
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ Logger.debug("PostFragment CreateView");
+ MainActivity activity = (MainActivity) getActivity();
+ PostState.getState().setListener(this);
+ UserPreferenceHelper preferenceHelper = new UserPreferenceHelper(activity);
+ View v = inflater.inflate(R.layout.fragment_post, null);
+ buttonTweet = getTweetButton(v);
+ buttonTweet.setOnClickListener(this);
+ editText = getEditText(v);
+ textViewCount = getCountTextView(v);
+ int textSize = preferenceHelper.getValue(R.string.key_setting_text_size, 10);
+ editText.addTextChangedListener(this);
+ editText.setOnFocusChangeListener(this);
+ editText.setTextSize(textSize + 4);
+ editText.setMovementMethod(new ArrowKeyMovementMethod()
+ {
+ @Override
+ protected boolean right(TextView widget, Spannable buffer)
+ {
+ //Don't back to Home
+ return widget.getSelectionEnd() == widget.length() || super.right(widget, buffer);
+ }
+ });
+ ImageButton imageButtonDeleteText = (ImageButton) v.findViewById(R.id.button_post_delete);
+ imageButtonDeleteText.setOnClickListener(this);
+ ImageButton imageButtonMedia = (ImageButton) v.findViewById(R.id.button_post_media);
+ imageButtonMedia.setOnClickListener(this);
+ ImageButton imageButtonMenu = (ImageButton) v.findViewById(R.id.button_post_menu);
+ imageButtonMenu.setOnClickListener(this);
+ //Reply view
+ viewGroupReply = getReplyViewGroup(v);
+ ImageButton imageButtonDeleteReply = (ImageButton) viewGroupReply.findViewById(R.id.button_post_reply_delete);
+ imageButtonDeleteReply.setOnClickListener(this);
+ //Media view
+ viewGroupMedia = getMediaViewGroup(v);
+ ImageView imageViewMedia = (ImageView) viewGroupMedia.findViewById(R.id.image_post_media);
+ ImageButton imageButtonDeleteMedia = (ImageButton) viewGroupMedia.findViewById(R.id.button_post_media_delete);
+ imageViewMedia.setOnClickListener(this);
+ imageButtonDeleteMedia.setOnClickListener(this);
+ editText.requestFocus();
+ return v;
+ }
+
+ @Override
+ public void onDestroyView()
+ {
+ Logger.debug("PostFragment DestroyView");
+ super.onDestroyView();
+ setStateFromView();
+ PostState.getState().removeListener();
+ }
+
+ @Override
+ public void onViewStateRestored(Bundle savedInstanceState)
+ {
+ Logger.debug("PostFragment ViewStateRestored");
+ super.onViewStateRestored(savedInstanceState);
+ PostState state = PostState.getState();
+ onPostStateChange(state);
+ }
+
+ private void deletePost()
+ {
+ editText.setText("");
+ PostState.getState().beginTransaction().setText("").setCursor(0).commit();
+ deleteReply();
+ }
+
+ private void deleteReply()
+ {
+ viewGroupReply.setVisibility(View.GONE);
+ PostState.getState().beginTransaction().setInReplyToStatusID(-1).commit();
+ }
+
+ private void displayImage()
+ {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.setDataAndType(Uri.fromFile(new File(PostState.getState().getMediaFilePath())), "image/*");
+ IntentUtils.startActivityIfFound(getActivity(), intent);
+ }
+
+ private TextView getCountTextView(View v)
+ {
+ return (TextView) v.findViewById(R.id.post_text_count);
+ }
+
+ private EditText getEditText(View v)
+ {
+ return (EditText) v.findViewById(R.id.post_edit_text);
+ }
+
+ private ViewGroup getMediaViewGroup(View v)
+ {
+ return (ViewGroup) v.findViewById(R.id.post_media_parent);
+ }
+
+ private ViewGroup getReplyViewGroup(View v)
+ {
+ return (ViewGroup) v.findViewById(R.id.post_inreplyto_parent);
+ }
+
+ private Button getTweetButton(View v)
+ {
+ return (Button) v.findViewById(R.id.button_post_tweet);
+ }
+
+ private void hideIME()
+ {
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
+ }
+
+ private void openPostMenu()
+ {
+ setStateFromView();
+ hideIME();
+ PostMenuDialogFragment menuDialogFragment = new PostMenuDialogFragment();
+ DialogHelper.showDialog(getActivity(), menuDialogFragment, PostMenuDialogFragment.TAG);
+ }
+
+ private void removeImage()
+ {
+ hideIME();
+ viewGroupMedia.setVisibility(View.GONE);
+ ((ImageView) viewGroupMedia.findViewById(R.id.image_post_media)).setImageBitmap(null);
+ PostState.getState().beginTransaction().setMediaFilePath("").commit();
+ }
+
+ private void setImage()
+ {
+ setStateFromView();
+ hideIME();
+ SelectImageDialogFragment selectImageDialogFragment = new SelectImageDialogFragment();
+ DialogHelper.showDialog(getActivity(), selectImageDialogFragment);
+ }
+
+ private void setStateFromView()
+ {
+ PostState state = PostState.getState();
+ state.removeListener();
+ state.beginTransaction()
+ .setText(editText.getText().toString())
+ .setSelection(editText.getSelectionStart(), editText.getSelectionEnd())
+ .commit();
+ state.setListener(this);
+ }
+
+ private void showIME()
+ {
+ if(editText != null)
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(editText, 0);
+ }
+ }.postDelayed(100);
+ }
+ }
+
+ private void submitPost()
+ {
+ hideIME();
+ setStateFromView();
+ PostState state = PostState.getState();
+ StatusUpdate statusUpdate = state.toStatusUpdate();
+ MainActivity mainActivity = (MainActivity) getActivity();
+ TweetTask tweetTask = new TweetTask(TwitterApi.getTwitter(mainActivity.getCurrentAccount()), statusUpdate, state.getMediaFilePath(), mainActivity);
+ tweetTask.execute();
+ PostState.newState().beginTransaction().commit();
+ mainActivity.setSelectedPageIndex(MainActivity.ADAPTER_HOME);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/SearchFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/SearchFragment.java
new file mode 100644
index 00000000..ace8fc36
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/SearchFragment.java
@@ -0,0 +1,407 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.method.ArrowKeyMovementMethod;
+import android.view.*;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ListView;
+import android.widget.TextView;
+import com.handmark.pulltorefresh.library.PullToRefreshBase;
+import com.handmark.pulltorefresh.library.PullToRefreshListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandOpenSearch;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.entity.SearchQuery;
+import net.lacolaco.smileessence.notification.NotificationType;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.twitter.StatusFilter;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.SearchTask;
+import net.lacolaco.smileessence.util.UIHandler;
+import net.lacolaco.smileessence.view.adapter.SearchListAdapter;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.SelectSearchQueryDialogFragment;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.Query;
+import twitter4j.QueryResult;
+import twitter4j.Twitter;
+
+import java.util.List;
+
+public class SearchFragment extends CustomListFragment implements View.OnClickListener, View.OnFocusChangeListener,
+ SearchListAdapter.OnQueryChangeListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String SEARCH_QUERY_DIALOG = "searchQueryDialog";
+ private EditText editText;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private int getAdapterIndex()
+ {
+ return getArguments().getInt(ADAPTER_INDEX);
+ }
+
+ private MainActivity getMainActivity()
+ {
+ return (MainActivity) getActivity();
+ }
+
+ @Override
+ protected PullToRefreshBase.Mode getRefreshMode()
+ {
+ return PullToRefreshBase.Mode.BOTH;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(View v)
+ {
+ switch(v.getId())
+ {
+ case R.id.button_search_queries:
+ {
+ openSearchQueryDialog(getMainActivity());
+ break;
+ }
+ case R.id.button_search_execute:
+ {
+ search();
+ break;
+ }
+ case R.id.button_search_save:
+ {
+ saveQuery();
+ }
+ }
+ }
+
+ // --------------------- Interface OnFocusChangeListener ---------------------
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus)
+ {
+ if(!hasFocus)
+ {
+ hideIME();
+ }
+ }
+
+ // --------------------- Interface OnQueryChangeListener ---------------------
+
+ @Override
+ public void onQueryChange(String newQuery)
+ {
+ if(editText != null)
+ {
+ editText.setText(newQuery);
+ }
+ }
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ @Override
+ public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = getMainActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final SearchListAdapter adapter = getListAdapter(activity);
+ String queryString = adapter.getQuery();
+ if(TextUtils.isEmpty(queryString))
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ notifyTextEmpty(activity);
+ refreshView.onRefreshComplete();
+ }
+ }.post();
+ return;
+ }
+ final Query query = SearchTask.getBaseQuery(activity, queryString);
+ if(adapter.getCount() > 0)
+ {
+ query.setSinceId(adapter.getTopID());
+ }
+ new SearchTask(twitter, query, activity)
+ {
+ @Override
+ protected void onPostExecute(QueryResult queryResult)
+ {
+ super.onPostExecute(queryResult);
+ if(queryResult != null)
+ {
+ java.util.List<twitter4j.Status> tweets = queryResult.getTweets();
+ for(int i = tweets.size() - 1; i >= 0; i--)
+ {
+ twitter4j.Status status = tweets.get(i);
+ if(!status.isRetweet())
+ {
+ StatusViewModel viewModel = new StatusViewModel(status, currentAccount);
+ adapter.addToTop(viewModel);
+ StatusFilter.filter(activity, viewModel);
+ }
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, true);
+ adapter.setTopID(queryResult.getMaxId());
+ refreshView.onRefreshComplete();
+ }
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = getMainActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final SearchListAdapter adapter = getListAdapter(activity);
+ String queryString = adapter.getQuery();
+ if(TextUtils.isEmpty(queryString))
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ notifyTextEmpty(activity);
+ refreshView.onRefreshComplete();
+ }
+ }.post();
+ return;
+ }
+ final Query query = SearchTask.getBaseQuery(activity, queryString);
+ if(adapter.getCount() > 0)
+ {
+ query.setMaxId(adapter.getLastID() - 1);
+ }
+ new SearchTask(twitter, query, activity)
+ {
+ @Override
+ protected void onPostExecute(QueryResult queryResult)
+ {
+ super.onPostExecute(queryResult);
+ if(queryResult != null)
+ {
+ List<twitter4j.Status> tweets = queryResult.getTweets();
+ for(twitter4j.Status status : tweets)
+ {
+ if(!status.isRetweet())
+ {
+ StatusViewModel viewModel = new StatusViewModel(status, currentAccount);
+ adapter.addToBottom(viewModel);
+ StatusFilter.filter(activity, viewModel);
+ }
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, false);
+ refreshView.onRefreshComplete();
+ }
+ }
+ }.execute();
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected PullToRefreshListView getListView(View page)
+ {
+ return (PullToRefreshListView) page.findViewById(R.id.listview_search);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
+ {
+ super.onCreateOptionsMenu(menu, inflater);
+ menu.removeItem(R.id.actionbar_search);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View page = inflater.inflate(R.layout.fragment_search, container, false);
+ int fragmentIndex = getAdapterIndex();
+ PullToRefreshListView listView = getListView(page);
+ SearchListAdapter adapter = (SearchListAdapter) getListAdapter(fragmentIndex);
+ listView.setAdapter(adapter);
+ listView.setOnScrollListener(this);
+ listView.setOnRefreshListener(this);
+ listView.setMode(getRefreshMode());
+ ImageButton buttonQueries = getQueriesButton(page);
+ buttonQueries.setOnClickListener(this);
+ ImageButton buttonExecute = getExecuteButton(page);
+ buttonExecute.setOnClickListener(this);
+ ImageButton buttonSave = getSaveButton(page);
+ buttonSave.setOnClickListener(this);
+ editText = getEditText(page);
+ editText.setOnFocusChangeListener(this);
+ editText.setText(adapter.getQuery());
+ editText.setMovementMethod(new ArrowKeyMovementMethod()
+ {
+ @Override
+ protected boolean right(TextView widget, Spannable buffer)
+ {
+ //Don't move page
+ return widget.getSelectionEnd() == widget.length() || super.right(widget, buffer);
+ }
+
+ @Override
+ protected boolean left(TextView widget, Spannable buffer)
+ {
+ //Don't move page
+ return widget.getSelectionStart() == 0 || super.left(widget, buffer);
+ }
+ });
+ adapter.setOnQueryChangeListener(this);
+ return page;
+ }
+
+ private EditText getEditText(View page)
+ {
+ return (EditText) page.findViewById(R.id.edittext_search);
+ }
+
+ private ImageButton getExecuteButton(View page)
+ {
+ return (ImageButton) page.findViewById(R.id.button_search_execute);
+ }
+
+ private SearchListAdapter getListAdapter(MainActivity activity)
+ {
+ return (SearchListAdapter) activity.getListAdapter(MainActivity.ADAPTER_SEARCH);
+ }
+
+ private ImageButton getQueriesButton(View page)
+ {
+ return (ImageButton) page.findViewById(R.id.button_search_queries);
+ }
+
+ private ImageButton getSaveButton(View page)
+ {
+ return (ImageButton) page.findViewById(R.id.button_search_save);
+ }
+
+ private void hideIME()
+ {
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
+ }
+
+ private void notifyTextEmpty(MainActivity activity)
+ {
+ Notificator.publish(activity, R.string.notice_search_text_empty);
+ }
+
+ private void openSearchQueryDialog(final MainActivity mainActivity)
+ {
+ if(SearchQuery.getAll().size() == 0)
+ {
+ Notificator.publish(mainActivity, R.string.notice_no_query_exists);
+ return;
+ }
+ DialogHelper.showDialog(mainActivity, new SelectSearchQueryDialogFragment()
+ {
+ @Override
+ protected void deleteQuery(CommandOpenSearch command)
+ {
+ super.deleteQuery(command);
+ if(editText.getText().toString().contentEquals(command.getQuery().query))
+ {
+ editText.setText("");
+ mainActivity.setLastSearch("");
+ }
+ else
+ {
+ mainActivity.setLastSearch(editText.getText().toString());
+ }
+ }
+
+ @Override
+ protected void executeCommand(Command command)
+ {
+ super.executeCommand(command);
+ SearchQuery query = ((CommandOpenSearch) command).getQuery();
+ editText.setText(query.query);
+ hideIME();
+ }
+ }, SEARCH_QUERY_DIALOG);
+ }
+
+ private void saveQuery()
+ {
+ String text = editText.getText().toString();
+ if(TextUtils.isEmpty(text))
+ {
+ Notificator.publish(getMainActivity(), R.string.notice_query_is_empty, NotificationType.ALERT);
+ }
+ else
+ {
+ SearchQuery.saveIfNotFound(text);
+ Notificator.publish(getMainActivity(), R.string.notice_query_saved);
+ }
+ }
+
+ private void search()
+ {
+ if(editText != null)
+ {
+ String text = editText.getText().toString();
+ if(TextUtils.isEmpty(text))
+ {
+ Notificator.publish(getMainActivity(), R.string.notice_query_is_empty, NotificationType.ALERT);
+ }
+ else
+ {
+ getMainActivity().openSearchPage(text);
+ hideIME();
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/SettingFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/SettingFragment.java
new file mode 100644
index 00000000..ebb1c290
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/SettingFragment.java
@@ -0,0 +1,212 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.EditTextPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.text.TextUtils;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.LicenseActivity;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.view.dialog.ConfirmDialogFragment;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.SimpleDialogFragment;
+
+import static android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+
+public class SettingFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener,
+ Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener
+{
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnPreferenceChangeListener ---------------------
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue)
+ {
+ String newValueStr = String.valueOf(newValue);
+ if(preference.getKey().contentEquals(getString(R.string.key_setting_text_size)))
+ {
+ if(TextUtils.isDigitsOnly(newValueStr))
+ {
+ int newTextSize = Integer.parseInt(newValueStr);
+ if(UserPreferenceHelper.TEXT_SIZE_MIN <= newTextSize && newTextSize <= UserPreferenceHelper.TEXT_SIZE_MAX)
+ {
+ return true;
+ }
+ Notificator.publish(getActivity(), R.string.error_setting_text_size_range);
+ }
+ else
+ {
+ Notificator.publish(getActivity(), R.string.error_setting_text_size_not_number);
+ }
+ return false;
+ }
+ else if(preference.getKey().contentEquals(getString(R.string.key_setting_timelines)))
+ {
+ if(TextUtils.isDigitsOnly(newValueStr))
+ {
+ int newTextSize = Integer.parseInt(newValueStr);
+ if(UserPreferenceHelper.TIMELINES_MIN <= newTextSize && newTextSize <= UserPreferenceHelper.TIMELINES_MAX)
+ {
+ return true;
+ }
+ Notificator.publish(getActivity(), R.string.error_setting_timelines_range);
+ }
+ else
+ {
+ Notificator.publish(getActivity(), R.string.error_setting_timelines_not_number);
+ }
+ return false;
+ }
+ else if(preference.getKey().contentEquals(getString(R.string.key_setting_theme)))
+ {
+ Notificator.publish(getActivity(), R.string.notice_theme_changed);
+ }
+ return true;
+ }
+
+ // --------------------- Interface OnPreferenceClickListener ---------------------
+
+ @Override
+ public boolean onPreferenceClick(Preference preference)
+ {
+ String key = preference.getKey();
+ if(key.contentEquals(getString(R.string.key_setting_application_information)))
+ {
+ SimpleDialogFragment informationDialog = SimpleDialogFragment.newInstance(
+ R.layout.dialog_app_info,
+ getString(R.string.dialog_title_about));
+ DialogHelper.showDialog(getActivity(), informationDialog);
+ }
+ else if(key.contentEquals(getString(R.string.key_setting_clear_account)))
+ {
+ ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_clear_account), new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Notificator.publish(getActivity(), R.string.notice_cleared_account);
+ Account.deleteAll();
+ finishActivity();
+ }
+ }, false);
+ }
+ else if(key.contentEquals(getString(R.string.key_setting_licenses)))
+ {
+ openLicenseActivity();
+ }
+ return true;
+ }
+
+ // --------------------- Interface OnSharedPreferenceChangeListener ---------------------
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
+ {
+ setSummaryCurrentValue();
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.setting);
+ EditTextPreference textSizePreference = (EditTextPreference) findPreference(R.string.key_setting_text_size);
+ textSizePreference.setSummary(textSizePreference.getText());
+ textSizePreference.setOnPreferenceChangeListener(this);
+ ListPreference themePreference = (ListPreference) findPreference(R.string.key_setting_theme);
+ themePreference.setSummary(themePreference.getEntry());
+ themePreference.setOnPreferenceChangeListener(this);
+ ListPreference namestylePreference = (ListPreference) findPreference(R.string.key_setting_namestyle);
+ namestylePreference.setSummary(namestylePreference.getEntry());
+ EditTextPreference timelinesPreference = (EditTextPreference) findPreference(R.string.key_setting_timelines);
+ timelinesPreference.setSummary(String.format(getString(R.string.setting_timelines_summary_format), timelinesPreference.getText()));
+ timelinesPreference.setOnPreferenceChangeListener(this);
+ Preference appInfoPreference = findPreference(R.string.key_setting_application_information);
+ appInfoPreference.setOnPreferenceClickListener(this);
+ Preference clearAccount = findPreference(R.string.key_setting_clear_account);
+ clearAccount.setOnPreferenceClickListener(this);
+ Preference license = findPreference(R.string.key_setting_licenses);
+ license.setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public void onPause()
+ {
+ super.onPause();
+ SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
+ sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onResume()
+ {
+ super.onResume();
+ SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
+ sharedPreferences.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public Preference findPreference(int preferenceResID)
+ {
+ return findPreference(getString(preferenceResID));
+ }
+
+ private void finishActivity()
+ {
+ getActivity().finish();
+ }
+
+ private void openLicenseActivity()
+ {
+ Intent intent = new Intent(getActivity(), LicenseActivity.class);
+ getActivity().startActivity(intent);
+ }
+
+ private void setSummaryCurrentValue()
+ {
+ EditTextPreference textSizePreference = (EditTextPreference) findPreference(R.string.key_setting_text_size);
+ textSizePreference.setSummary(textSizePreference.getText());
+ ListPreference themePreference = (ListPreference) findPreference(R.string.key_setting_theme);
+ themePreference.setSummary(themePreference.getEntry());
+ ListPreference namestylePreference = (ListPreference) findPreference(R.string.key_setting_namestyle);
+ namestylePreference.setSummary(namestylePreference.getEntry());
+ EditTextPreference timelinesPreference = (EditTextPreference) findPreference(R.string.key_setting_timelines);
+ timelinesPreference.setSummary(String.format(getString(R.string.setting_timelines_summary_format), timelinesPreference.getText()));
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/TextFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/TextFragment.java
new file mode 100644
index 00000000..f0fec169
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/TextFragment.java
@@ -0,0 +1,59 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class TextFragment extends Fragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String ARG_TEXT = "text";
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ TextView textView = new TextView(getActivity());
+ Bundle args = getArguments();
+ if(args != null)
+ {
+ String text = args.getString(ARG_TEXT);
+ if(!TextUtils.isEmpty(text))
+ {
+ textView.setText(text);
+ }
+ }
+ return textView;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/UserListFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/UserListFragment.java
new file mode 100644
index 00000000..f2aaa823
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/UserListFragment.java
@@ -0,0 +1,242 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view;
+
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.ListView;
+import android.widget.TextView;
+import com.handmark.pulltorefresh.library.PullToRefreshBase;
+import com.handmark.pulltorefresh.library.PullToRefreshListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.twitter.StatusFilter;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.UserListStatusesTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.UIHandler;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.SelectUserListDialogFragment;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import net.lacolaco.smileessence.viewmodel.UserListListAdapter;
+import twitter4j.Paging;
+import twitter4j.Twitter;
+
+public class UserListFragment extends CustomListFragment implements View.OnClickListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private TextView textListName;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private MainActivity getMainActivity()
+ {
+ return (MainActivity) getActivity();
+ }
+
+ @Override
+ protected PullToRefreshBase.Mode getRefreshMode()
+ {
+ return PullToRefreshBase.Mode.BOTH;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(View v)
+ {
+ int id = v.getId();
+ switch(id)
+ {
+ case R.id.button_userlist_lists:
+ {
+ openUserListsDialog(getMainActivity());
+ break;
+ }
+ }
+ }
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ @Override
+ public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = getMainActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final UserListListAdapter adapter = getListAdapter(activity);
+ String listFullName = adapter.getListFullName();
+ if(TextUtils.isEmpty(listFullName))
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ notifyTextEmpty(activity);
+ refreshView.onRefreshComplete();
+ }
+ }.post();
+ return;
+ }
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setSinceId(adapter.getTopID());
+ }
+ new UserListStatusesTask(twitter, listFullName, activity, paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(int i = statuses.length - 1; i >= 0; i--)
+ {
+ twitter4j.Status status = statuses[i];
+ StatusViewModel statusViewModel = new StatusViewModel(status, activity.getCurrentAccount());
+ adapter.addToTop(statusViewModel);
+ StatusFilter.filter(activity, statusViewModel);
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, true);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = getMainActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final UserListListAdapter adapter = getListAdapter(activity);
+ String listFullName = adapter.getListFullName();
+ if(TextUtils.isEmpty(listFullName))
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ notifyTextEmpty(activity);
+ refreshView.onRefreshComplete();
+ }
+ }.post();
+ return;
+ }
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setMaxId(adapter.getLastID() - 1);
+ }
+ new UserListStatusesTask(twitter, listFullName, activity, paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(int i = 0; i < statuses.length; i++)
+ {
+ twitter4j.Status status = statuses[i];
+ StatusViewModel statusViewModel = new StatusViewModel(status, activity.getCurrentAccount());
+ adapter.addToBottom(statusViewModel);
+ StatusFilter.filter(activity, statusViewModel);
+ }
+ updateListViewWithNotice(refreshView.getRefreshableView(), adapter, false);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected PullToRefreshListView getListView(View page)
+ {
+ return (PullToRefreshListView) page.findViewById(R.id.listview_userlist);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View page = inflater.inflate(R.layout.fragment_userlist, container, false);
+ PullToRefreshListView listView = getListView(page);
+ UserListListAdapter adapter = getListAdapter((MainActivity) getActivity());
+ listView.setAdapter(adapter);
+ listView.setOnScrollListener(this);
+ listView.setOnRefreshListener(this);
+ listView.setMode(getRefreshMode());
+ ImageButton buttonUserLists = getUserListsButton(page);
+ buttonUserLists.setOnClickListener(this);
+ textListName = getTextListName(page);
+ textListName.setText(adapter.getListFullName());
+ return page;
+ }
+
+ private UserListListAdapter getListAdapter(MainActivity activity)
+ {
+ return (UserListListAdapter) getListAdapter(MainActivity.ADAPTER_USERLIST);
+ }
+
+ private TextView getTextListName(View page)
+ {
+ return (TextView) page.findViewById(R.id.textview_userlist_name);
+ }
+
+ private ImageButton getUserListsButton(View page)
+ {
+ return (ImageButton) page.findViewById(R.id.button_userlist_lists);
+ }
+
+ private void notifyTextEmpty(MainActivity activity)
+ {
+ Notificator.publish(activity, R.string.notice_userlist_not_selected);
+ }
+
+ private void openUserListsDialog(final MainActivity mainActivity)
+ {
+ DialogHelper.showDialog(mainActivity, new SelectUserListDialogFragment()
+ {
+ @Override
+ public void onDismiss(DialogInterface dialog)
+ {
+ super.onDismiss(dialog);
+ textListName.setText(getListAdapter(mainActivity).getListFullName());
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/CustomListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/CustomListAdapter.java
new file mode 100644
index 00000000..3e598941
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/CustomListAdapter.java
@@ -0,0 +1,209 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import android.app.Activity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import com.google.common.collect.Iterables;
+import net.lacolaco.smileessence.util.UIHandler;
+import net.lacolaco.smileessence.viewmodel.IViewModel;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class CustomListAdapter<T extends IViewModel> extends BaseAdapter
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ protected final Object LOCK = new Object();
+ protected Class<T> clss;
+ protected ArrayList<T> list = new ArrayList<>();
+ protected T[] array;
+ protected int count;
+ protected boolean isNotifiable = true;
+ protected Activity activity;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CustomListAdapter(Activity activity, Class<T> clss)
+ {
+ this.activity = activity;
+ this.clss = clss;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public Activity getActivity()
+ {
+ return activity;
+ }
+
+ @Override
+ public int getCount()
+ {
+ return count;
+ }
+
+ public boolean isNotifiable()
+ {
+ synchronized(LOCK)
+ {
+ return isNotifiable;
+ }
+ }
+
+ public void setNotifiable(boolean notifiable)
+ {
+ synchronized(LOCK)
+ {
+ isNotifiable = notifiable;
+ }
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface Adapter ---------------------
+
+ @Override
+ public Object getItem(int position)
+ {
+ return array[position];
+ }
+
+ @Override
+ public long getItemId(int position)
+ {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent)
+ {
+ return ((T) getItem(position)).getView(activity, activity.getLayoutInflater(), convertView);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void notifyDataSetChanged()
+ {
+ sort();
+ array = Iterables.toArray(list, clss);
+ count = array.length;
+ super.notifyDataSetChanged();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void addToBottom(T... items)
+ {
+ synchronized(LOCK)
+ {
+ List<T> buffer = Arrays.asList(items);
+ for(T item : buffer)
+ {
+ if(list.contains(item))
+ {
+ list.remove(item);
+ }
+ list.add(item);
+ }
+ }
+ }
+
+ public void addToTop(T... items)
+ {
+ synchronized(LOCK)
+ {
+ List<T> buffer = Arrays.asList(items);
+ Collections.reverse(buffer);
+ for(T item : buffer)
+ {
+ if(list.contains(item))
+ {
+ list.remove(item);
+ }
+ list.add(0, item);
+ }
+ }
+ }
+
+ public void clear()
+ {
+ synchronized(LOCK)
+ {
+ list.clear();
+ }
+ }
+
+ public T removeItem(int position)
+ {
+ synchronized(LOCK)
+ {
+ return list.remove(position);
+ }
+ }
+
+ public boolean removeItem(T item)
+ {
+ synchronized(LOCK)
+ {
+ return list.remove(item);
+ }
+ }
+
+ public void sort()
+ {
+ }
+
+ public void update()
+ {
+ if(isNotifiable)
+ {
+ updateForce();
+ }
+ }
+
+ public void updateForce()
+ {
+ synchronized(LOCK)
+ {
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ notifyDataSetChanged();
+ }
+ }.post();
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/EventListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/EventListAdapter.java
new file mode 100644
index 00000000..5949d9b5
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/EventListAdapter.java
@@ -0,0 +1,39 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.viewmodel.EventViewModel;
+
+public class EventListAdapter extends CustomListAdapter<EventViewModel>
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public EventListAdapter(Activity activity)
+ {
+ super(activity, EventViewModel.class);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/MessageListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/MessageListAdapter.java
new file mode 100644
index 00000000..f88a8cb0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/MessageListAdapter.java
@@ -0,0 +1,125 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.viewmodel.MessageViewModel;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+
+public class MessageListAdapter extends CustomListAdapter<MessageViewModel>
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MessageListAdapter(Activity activity)
+ {
+ super(activity, MessageViewModel.class);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getLastID()
+ {
+ return ((MessageViewModel) getItem(getCount() - 1)).getID();
+ }
+
+ public long getTopID()
+ {
+ return ((MessageViewModel) getItem(0)).getID();
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void addToBottom(MessageViewModel... items)
+ {
+ for(MessageViewModel item : items)
+ {
+ if(!preAdd(item))
+ {
+ continue;
+ }
+ super.addToBottom(items);
+ }
+ }
+
+ @Override
+ public void addToTop(MessageViewModel... items)
+ {
+ for(MessageViewModel item : items)
+ {
+ if(!preAdd(item))
+ {
+ continue;
+ }
+ super.addToTop(items);
+ }
+ }
+
+ @Override
+ public void sort()
+ {
+ synchronized(LOCK)
+ {
+ Collections.sort(list, new Comparator<MessageViewModel>()
+ {
+ @Override
+ public int compare(MessageViewModel lhs, MessageViewModel rhs)
+ {
+ return rhs.getCreatedAt().compareTo(lhs.getCreatedAt());
+ }
+ });
+ }
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public MessageViewModel removeByMessageID(long messageID)
+ {
+ synchronized(this.LOCK)
+ {
+ Iterator<MessageViewModel> iterator = this.list.iterator();
+ while(iterator.hasNext())
+ {
+ MessageViewModel message = iterator.next();
+ if(message.getID() == messageID)
+ {
+ iterator.remove();
+ return message;
+ }
+ }
+ return null;
+ }
+ }
+
+ private boolean preAdd(MessageViewModel item)
+ {
+ removeByMessageID(item.getID());
+ return true;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/PageListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/PageListAdapter.java
new file mode 100644
index 00000000..c1966a00
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/PageListAdapter.java
@@ -0,0 +1,207 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import android.app.ActionBar;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.v13.app.FragmentStatePagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.widget.ArrayAdapter;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.logging.Logger;
+
+import java.util.ArrayList;
+
+public class PageListAdapter extends FragmentStatePagerAdapter implements ViewPager.OnPageChangeListener,
+ ActionBar.OnNavigationListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final MainActivity context;
+ private final ActionBar actionBar;
+ private final ViewPager viewPager;
+ private final ArrayList<PageInfo> pages = new ArrayList<>();
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public PageListAdapter(MainActivity activity, ViewPager viewPager)
+ {
+ super(activity.getFragmentManager());
+ this.context = activity;
+ this.actionBar = activity.getActionBar();
+ this.viewPager = viewPager;
+ viewPager.setAdapter(this);
+ viewPager.setOnPageChangeListener(this);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ @Override
+ public synchronized int getCount()
+ {
+ return pages.size();
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnNavigationListener ---------------------
+
+ @Override
+ public synchronized boolean onNavigationItemSelected(int itemPosition, long itemId)
+ {
+ viewPager.setCurrentItem(itemPosition, true);
+ return true;
+ }
+
+ // --------------------- Interface OnPageChangeListener ---------------------
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
+ {
+ }
+
+ @Override
+ public synchronized void onPageSelected(int position)
+ {
+ //Synchronize pager and navigation.
+ Logger.debug(String.format("Page selected:%d", position));
+ actionBar.setSelectedNavigationItem(position);
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state)
+ {
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ /**
+ * Add new tab and new page
+ *
+ * @param name Page name
+ * @param clss Fragment class
+ * @param args Bundle for Fragment instantiate
+ * @return True if adding is complete successfully
+ */
+ public synchronized boolean addPage(String name, Class<? extends Fragment> clss, Bundle args)
+ {
+ if(addPageWithoutNotify(name, clss, args))
+ {
+ refreshListNavigation();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Add new tab and new page without notify.
+ * You must call notifyDataSetChanged after adding tab.
+ *
+ * @param name Page name
+ * @param clss Fragment class
+ * @param args Bundle for Fragment instantiate
+ * @return True if adding is complete successfully
+ */
+ public synchronized boolean addPageWithoutNotify(String name, Class<? extends Fragment> clss, Bundle args)
+ {
+ PageInfo info = new PageInfo(name, clss, args);
+ return pages.add(info);
+ }
+
+ @Override
+ public synchronized Fragment getItem(int position)
+ {
+ PageInfo info = pages.get(position);
+ return Fragment.instantiate(context, info.fragmentClass.getName(), info.args);
+ }
+
+ public synchronized PageInfo getPage(int position)
+ {
+ return pages.get(position);
+ }
+
+ public synchronized void refreshListNavigation()
+ {
+ ArrayList<String> itemList = new ArrayList<>();
+ for(PageInfo page : pages)
+ {
+ itemList.add(page.name);
+ }
+ ArrayAdapter<String> adapter = new ArrayAdapter<>(context, R.layout.navigation_list_item, R.id.navigation_list_item_text, itemList);
+ actionBar.setListNavigationCallbacks(adapter, this);
+ notifyDataSetChanged();
+ }
+
+ public synchronized boolean removePage(int position)
+ {
+ if(removePageWithoutNotify(position))
+ {
+ refreshListNavigation();
+ return true;
+ }
+ return false;
+ }
+
+ private synchronized boolean removePageWithoutNotify(int position)
+ {
+ return pages.remove(position) != null;
+ }
+
+ // -------------------------- INNER CLASSES --------------------------
+
+ public static final class PageInfo
+ {
+
+ private final String name;
+ private final Class<? extends Fragment> fragmentClass;
+ private final Bundle args;
+
+ PageInfo(String name, Class<? extends Fragment> clss, Bundle args)
+ {
+ this.name = name;
+ this.fragmentClass = clss;
+ this.args = args;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public Class<? extends Fragment> getFragmentClass()
+ {
+ return fragmentClass;
+ }
+
+ public Bundle getArgs()
+ {
+ return args;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/PostState.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/PostState.java
new file mode 100644
index 00000000..f7e0fa0f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/PostState.java
@@ -0,0 +1,232 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import twitter4j.StatusUpdate;
+
+public class PostState
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static PostState instance = new PostState();
+ private String text = "";
+ private long inReplyToStatusID = -1L;
+ private String inReplyToScreenName = "";
+ private String inReplyToText = "";
+ private String mediaFilePath = "";
+ private boolean directMessage = false;
+ private OnPostStateChangeListener listener;
+ private int selectionStart = 0;
+ private int selectionEnd = 0;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ private PostState()
+ {
+ }
+
+ public static PostState getState()
+ {
+ return instance;
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static PostState newState()
+ {
+ return instance = new PostState().setListener(instance.listener);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getInReplyToStatusID()
+ {
+ return inReplyToStatusID;
+ }
+
+ public String getMediaFilePath()
+ {
+ return mediaFilePath;
+ }
+
+ public int getSelectionEnd()
+ {
+ if(selectionEnd < 0)
+ {
+ return text.length();
+ }
+ return selectionEnd;
+ }
+
+ public int getSelectionStart()
+ {
+ if(selectionStart < 0)
+ {
+ return text.length();
+ }
+ return selectionStart;
+ }
+
+ public String getText()
+ {
+ return text;
+ }
+
+ public PostState setListener(OnPostStateChangeListener listener)
+ {
+ this.listener = listener;
+ return this;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public PostStateTransaction beginTransaction()
+ {
+ return new PostStateTransaction(this);
+ }
+
+ public void removeListener()
+ {
+ this.listener = null;
+ }
+
+ /**
+ * Convert to StatusUpdate for tweet.
+ *
+ * @return StatusUpdate
+ */
+ public StatusUpdate toStatusUpdate()
+ {
+ return new StatusUpdate(getText())
+ .inReplyToStatusId(getInReplyToStatusID());
+ }
+
+ private PostState copy(PostState another)
+ {
+ this.text = another.text;
+ this.inReplyToStatusID = another.inReplyToStatusID;
+ this.inReplyToScreenName = another.inReplyToScreenName;
+ this.inReplyToText = another.inReplyToText;
+ this.mediaFilePath = another.mediaFilePath;
+ this.directMessage = another.directMessage;
+ this.selectionStart = another.selectionStart;
+ this.selectionEnd = another.selectionEnd;
+ this.listener = another.listener;
+ return this;
+ }
+
+ private void postStateChange()
+ {
+ if(listener != null)
+ {
+ listener.onPostStateChange(this);
+ }
+ }
+
+ // -------------------------- INNER CLASSES --------------------------
+
+ public static interface OnPostStateChangeListener
+ {
+
+ void onPostStateChange(PostState postState);
+ }
+
+ public static class PostStateTransaction
+ {
+
+ private PostState state;
+
+ private PostStateTransaction(PostState state)
+ {
+ this.state = new PostState().copy(state);
+ }
+
+ public PostStateTransaction setText(String text)
+ {
+ state.text = text;
+ return this;
+ }
+
+ public PostStateTransaction appendText(String text)
+ {
+ state.text = state.text + text;
+ return this;
+ }
+
+ public PostStateTransaction insertText(int index, String text)
+ {
+ StringBuilder builder = new StringBuilder(state.text);
+ builder.insert(index, text);
+ state.text = builder.toString();
+ return this;
+ }
+
+ public PostStateTransaction setInReplyToStatusID(long inReplyToStatusID)
+ {
+ state.inReplyToStatusID = inReplyToStatusID;
+ return this;
+ }
+
+ public PostStateTransaction setMediaFilePath(String mediaFilePath)
+ {
+ state.mediaFilePath = mediaFilePath;
+ return this;
+ }
+
+ public PostStateTransaction setCursor(int cursor)
+ {
+ state.selectionStart = state.selectionEnd = cursor;
+ return this;
+ }
+
+ public PostStateTransaction setSelection(int start, int end)
+ {
+ state.selectionStart = start;
+ state.selectionEnd = end;
+ return this;
+ }
+
+ public void commit()
+ {
+ PostState.getState().copy(state).postStateChange();
+ }
+
+ public void commitWithOpen(MainActivity activity)
+ {
+ DialogHelper.closeAll(activity);
+ PostState.getState().copy(state).postStateChange();
+ activity.openPostPage();
+ }
+
+ public PostStateTransaction moveCursor(int length)
+ {
+ int cursor = state.selectionEnd + length;
+ return setCursor(cursor);
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/SearchListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/SearchListAdapter.java
new file mode 100644
index 00000000..178bb7f1
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/SearchListAdapter.java
@@ -0,0 +1,93 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import android.app.Activity;
+
+public class SearchListAdapter extends StatusListAdapter
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private long topID;
+ private String query;
+ private OnQueryChangeListener listener;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public SearchListAdapter(Activity activity)
+ {
+ super(activity);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public OnQueryChangeListener getListener()
+ {
+ return listener;
+ }
+
+ public String getQuery()
+ {
+ return query;
+ }
+
+ @Override
+ public long getTopID()
+ {
+ return topID;
+ }
+
+ public void setTopID(long topID)
+ {
+ this.topID = topID;
+ }
+
+ public void setOnQueryChangeListener(OnQueryChangeListener listener)
+ {
+ this.listener = listener;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void initSearch(String query)
+ {
+ this.query = query;
+ topID = 0;
+ if(listener != null)
+ {
+ listener.onQueryChange(query);
+ }
+ }
+
+ // -------------------------- INNER CLASSES --------------------------
+
+ public static interface OnQueryChangeListener
+ {
+
+ void onQueryChange(String newQuery);
+ }
+
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/StatusListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/StatusListAdapter.java
new file mode 100644
index 00000000..7ab5287f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/adapter/StatusListAdapter.java
@@ -0,0 +1,132 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.adapter;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+
+public class StatusListAdapter extends CustomListAdapter<StatusViewModel>
+{
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusListAdapter(Activity activity)
+ {
+ super(activity, StatusViewModel.class);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getLastID()
+ {
+ return ((StatusViewModel) getItem(getCount() - 1)).getID();
+ }
+
+ public long getTopID()
+ {
+ return ((StatusViewModel) getItem(0)).getID();
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void addToBottom(StatusViewModel... items)
+ {
+ for(StatusViewModel item : items)
+ {
+ if(!preAdd(item))
+ {
+ continue;
+ }
+ super.addToBottom(item);
+ }
+ }
+
+ @Override
+ public void addToTop(StatusViewModel... items)
+ {
+ for(StatusViewModel item : items)
+ {
+ if(!preAdd(item))
+ {
+ continue;
+ }
+ super.addToTop(item);
+ }
+ }
+
+ /**
+ * Sort list by Status#createdAt
+ */
+ @Override
+ public void sort()
+ {
+ synchronized(LOCK)
+ {
+ Collections.sort(list, new Comparator<StatusViewModel>()
+ {
+ @Override
+ public int compare(StatusViewModel lhs, StatusViewModel rhs)
+ {
+ return Long.valueOf(rhs.getID()).compareTo(lhs.getID());
+ }
+ });
+ }
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void removeByStatusID(long statusID)
+ {
+ synchronized(this.LOCK)
+ {
+ Iterator<StatusViewModel> iterator = this.list.iterator();
+ while(iterator.hasNext())
+ {
+ StatusViewModel statusViewModel = iterator.next();
+ if(statusViewModel.getID() == statusID || statusViewModel.getOriginal().getID() == statusID)
+ {
+ iterator.remove();
+ }
+ }
+ }
+ }
+
+ private boolean isBlockUser(StatusViewModel item)
+ {
+ return UserCache.getInstance().isInvisibleUserID(item.getOriginalUserID());
+ }
+
+ private boolean preAdd(StatusViewModel item)
+ {
+ removeByStatusID(item.getID());
+ return !isBlockUser(item);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ChooseTemplateDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ChooseTemplateDialogFragment.java
new file mode 100644
index 00000000..ceceb6e8
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ChooseTemplateDialogFragment.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.post.PostCommandUseTemplate;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.entity.Template;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChooseTemplateDialogFragment extends MenuDialogFragment
+{
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ Account account = activity.getCurrentAccount();
+ List<Command> commands = getCommands(activity);
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ listView.setOnItemClickListener(onItemClickListener);
+
+ return new AlertDialog.Builder(activity)
+ .setView(body)
+ .setCancelable(true)
+ .create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public List<Command> getCommands(Activity activity)
+ {
+ ArrayList<Command> list = new ArrayList<>();
+ List<Template> templates = Template.getAll();
+ for(Template template : templates)
+ {
+ list.add(new PostCommandUseTemplate(activity, template));
+ }
+ return list;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ConfirmDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ConfirmDialogFragment.java
new file mode 100644
index 00000000..822f607f
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ConfirmDialogFragment.java
@@ -0,0 +1,142 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+
+public abstract class ConfirmDialogFragment extends DialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String ARG_TEXT = "text";
+ public static final String TAG = "confirmDialog";
+ private final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ onButtonClick(which);
+ dialog.dismiss();
+ }
+ };
+ private int layoutResourceID;
+ private String text;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static void show(Activity activity, String text, final Runnable onYes)
+ {
+ show(activity, text, onYes, null, true);
+ }
+
+ public static void show(Activity activity, String text, final Runnable onYes, boolean ignorable)
+ {
+ show(activity, text, onYes, null, ignorable);
+ }
+
+ public static void show(Activity activity, String text, final Runnable onOK, final Runnable onCancel, boolean ignorable)
+ {
+ boolean confirm = new UserPreferenceHelper(activity).getValue(R.string.key_setting_show_confirm_dialog, true);
+ if(!confirm && ignorable)
+ {
+ onOK.run();
+ return;
+ }
+ final ConfirmDialogFragment fragment = new ConfirmDialogFragment()
+ {
+ @Override
+ public void onButtonClick(int which)
+ {
+ switch(which)
+ {
+ case DialogInterface.BUTTON_POSITIVE:
+ {
+ if(onOK != null)
+ {
+ this.dismiss();
+ onOK.run();
+ }
+ break;
+ }
+ case DialogInterface.BUTTON_NEGATIVE:
+ {
+ if(onCancel != null)
+ {
+ this.dismiss();
+ onCancel.run();
+ }
+ break;
+ }
+ }
+ }
+ };
+ fragment.setText(text);
+ DialogHelper.showDialog(activity, fragment, TAG);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public void setText(String text)
+ {
+ Bundle args = new Bundle();
+ args.putString(ARG_TEXT, text);
+ setArguments(args);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ if(args != null)
+ {
+ text = args.getString(ARG_TEXT);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ return new AlertDialog.Builder(getActivity()).setTitle(text)
+ .setCancelable(false)
+ .setPositiveButton(R.string.alert_dialog_ok, listener)
+ .setNegativeButton(R.string.alert_dialog_cancel, listener)
+ .create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public abstract void onButtonClick(int which);
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/DialogHelper.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/DialogHelper.java
new file mode 100644
index 00000000..fa87f681
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/DialogHelper.java
@@ -0,0 +1,108 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.DialogFragment;
+import android.app.FragmentTransaction;
+
+import java.util.Stack;
+
+public class DialogHelper
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final String TAG_DIALOG = "dialog";
+
+ private static Stack<String> dialogStack = new Stack<>();
+ private final Activity activity;
+ private final DialogFragment dialogFragment;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public DialogHelper(Activity activity, DialogFragment dialogFragment)
+ {
+ this.activity = activity;
+ this.dialogFragment = dialogFragment;
+ }
+
+ public static void closeDialog(Activity activity)
+ {
+ close(activity, TAG_DIALOG);
+ }
+
+ /**
+ * Close all stacked dialog
+ */
+ public static void closeAll(Activity activity)
+ {
+ while(dialogStack.size() > 0)
+ {
+ String tag = dialogStack.pop();
+ close(activity, tag);
+ }
+ }
+
+ public static void showDialog(Activity activity, DialogFragment dialogFragment)
+ {
+ showDialog(activity, dialogFragment, TAG_DIALOG);
+ }
+
+ /**
+ * Please expressly closing
+ */
+ public static void showDialog(Activity activity, DialogFragment dialogFragment, String tag)
+ {
+ close(activity, tag);
+ dialogStack.push(tag);
+ dialogFragment.show(activity.getFragmentManager().beginTransaction(), tag);
+ }
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public static void close(Activity activity, String tag)
+ {
+ if(activity != null)
+ {
+ FragmentTransaction transaction = activity.getFragmentManager().beginTransaction();
+ DialogFragment oldDialog = (DialogFragment) activity.getFragmentManager().findFragmentByTag(tag);
+ if(oldDialog != null)
+ {
+ transaction.remove(oldDialog);
+ // oldDialog.dismiss();
+ }
+ // transaction.addToBackStack(null);
+ transaction.commit();
+ }
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void show()
+ {
+ showDialog(activity, dialogFragment);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/DisposeDialog.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/DisposeDialog.java
new file mode 100644
index 00000000..1d9ef1d0
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/DisposeDialog.java
@@ -0,0 +1,56 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+
+/**
+ * Dialog for dispose soon.
+ */
+public final class DisposeDialog extends Dialog
+{
+
+ public DisposeDialog(Context context)
+ {
+ super(context);
+ }
+
+ public DisposeDialog(Context context, int theme)
+ {
+ super(context, theme);
+ }
+
+ protected DisposeDialog(Context context, boolean cancelable, OnCancelListener cancelListener)
+ {
+ super(context, cancelable, cancelListener);
+ }
+
+ @Override
+ public void show()
+ {
+ dismiss();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/EditTextDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/EditTextDialogFragment.java
new file mode 100644
index 00000000..763467ba
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/EditTextDialogFragment.java
@@ -0,0 +1,98 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+import net.lacolaco.smileessence.R;
+
+public abstract class EditTextDialogFragment extends DialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static String titleKey = "title";
+ private static String textKey = "text";
+ private String title;
+ private String text;
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ text = args.getString(textKey);
+ title = args.getString(titleKey);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ View view = getActivity().getLayoutInflater().inflate(R.layout.part_edittext, null);
+ final EditText editText = (EditText) view.findViewById(R.id.part_editText);
+ editText.setText(text);
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(title)
+ .setView(view)
+ .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ onTextInput(editText.getText().toString());
+ dialog.dismiss();
+ }
+ })
+ .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ dialog.dismiss();
+ }
+ })
+ .create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public abstract void onTextInput(String text);
+
+ public void setParams(String title, String text)
+ {
+ Bundle args = new Bundle();
+ args.putString(titleKey, title);
+ args.putString(textKey, text);
+ setArguments(args);
+ }
+
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/HashtagDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/HashtagDialogFragment.java
new file mode 100644
index 00000000..7a38c855
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/HashtagDialogFragment.java
@@ -0,0 +1,100 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandPasteToPost;
+import net.lacolaco.smileessence.command.CommandSaveAsTemplate;
+import net.lacolaco.smileessence.command.CommandSearchOnTwitter;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class HashtagDialogFragment extends MenuDialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String KEY_TEXT = "text";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private String getHashtagText()
+ {
+ return "#" + (String) getArguments().get(KEY_TEXT);
+ }
+
+ public void setText(String text)
+ {
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_TEXT, text);
+ setArguments(bundle);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ Account account = activity.getCurrentAccount();
+ String text = getHashtagText();
+ List<Command> commands = getCommands(activity, text);
+ Command.filter(commands);
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ listView.setOnItemClickListener(onItemClickListener);
+
+ return new AlertDialog.Builder(activity).setView(body).setTitle(text).setCancelable(true).create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public List<Command> getCommands(Activity activity, String text)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ commands.add(new CommandSaveAsTemplate(activity, text));
+ commands.add(new CommandPasteToPost(activity, text));
+ commands.add(new CommandSearchOnTwitter(activity, text));
+ return commands;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MenuDialogFragment.java
new file mode 100644
index 00000000..7282e366
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MenuDialogFragment.java
@@ -0,0 +1,79 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.DialogFragment;
+import android.view.View;
+import android.widget.AdapterView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.IConfirmable;
+
+public abstract class MenuDialogFragment extends DialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ protected final AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener()
+ {
+ @Override
+ public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
+ {
+ MenuDialogFragment.this.onItemClick(adapterView, i);
+ }
+ };
+
+ protected void executeCommand(Command command)
+ {
+ if(command.execute())
+ {
+ dismiss();
+ DialogHelper.closeAll(getActivity());
+ }
+ }
+
+ protected void onItemClick(AdapterView<?> adapterView, int i)
+ {
+ final Command command = (Command) adapterView.getItemAtPosition(i);
+ if(command != null)
+ {
+ if(command instanceof IConfirmable)
+ {
+ ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ executeCommand(command);
+ }
+ });
+ }
+ else
+ {
+ executeCommand(command);
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MessageDetailDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MessageDetailDialogFragment.java
new file mode 100644
index 00000000..cbb43b71
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MessageDetailDialogFragment.java
@@ -0,0 +1,283 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ListView;
+import com.google.common.collect.Lists;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandOpenURL;
+import net.lacolaco.smileessence.data.DirectMessageCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.DeleteMessageTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.MessageListAdapter;
+import net.lacolaco.smileessence.viewmodel.MessageViewModel;
+import twitter4j.DirectMessage;
+import twitter4j.MediaEntity;
+import twitter4j.URLEntity;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class MessageDetailDialogFragment extends DialogFragment implements View.OnClickListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final String KEY_MESSAGE_ID = "messageID";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getMessageID()
+ {
+ return getArguments().getLong(KEY_MESSAGE_ID);
+ }
+
+ public void setMessageID(long messageID)
+ {
+ Bundle args = new Bundle();
+ args.putLong(KEY_MESSAGE_ID, messageID);
+ setArguments(args);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(final View v)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+ TwitterUtils.tryGetMessage(account, getMessageID(), new TwitterUtils.MessageCallback()
+ {
+ @Override
+ public void success(DirectMessage message)
+ {
+ switch(v.getId())
+ {
+ case R.id.button_status_detail_reply:
+ {
+ openSendMessageDialog(message);
+ break;
+ }
+ case R.id.button_status_detail_delete:
+ {
+ deleteMessage(account, message);
+ break;
+ }
+ case R.id.button_status_detail_menu:
+ {
+ openMenu(activity);
+ break;
+ }
+ default:
+ {
+ dismiss();
+ }
+ }
+ }
+
+ @Override
+ public void error()
+ {
+
+ }
+ });
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+
+ DirectMessage selectedMessage = DirectMessageCache.getInstance().get(getMessageID());
+ if(selectedMessage == null)
+ {
+ Notificator.publish(getActivity(), R.string.notice_error_get_messages);
+ return new DisposeDialog(getActivity());
+ }
+ View header = getTitleView(activity, account, selectedMessage);
+ ListView listView = (ListView) header.findViewById(R.id.listview_status_detail_reply_to);
+ final MessageListAdapter adapter = new MessageListAdapter(getActivity());
+ listView.setAdapter(adapter);
+ long replyToMessageId = -1;
+ ArrayList<DirectMessage> allMessages = Lists.newArrayList(DirectMessageCache.getInstance().all());
+ Collections.sort(allMessages, new Comparator<DirectMessage>()
+ {
+ @Override
+ public int compare(DirectMessage lhs, DirectMessage rhs)
+ {
+ return rhs.getCreatedAt().compareTo(lhs.getCreatedAt());
+ }
+ });
+ for(DirectMessage directMessage : allMessages)
+ {
+ if(selectedMessage.getId() == directMessage.getId())
+ {
+ continue;
+ }
+ if(directMessage.getCreatedAt().getTime() > selectedMessage.getCreatedAt().getTime())
+ {
+ continue;
+ }
+ if(directMessage.getSenderId() == selectedMessage.getRecipientId() && directMessage.getRecipientId() == selectedMessage.getSenderId())
+ {
+ replyToMessageId = directMessage.getId();
+ break;
+ }
+ }
+
+ if(replyToMessageId == -1)
+ {
+ listView.setVisibility(View.GONE);
+ }
+ else
+ {
+ TwitterUtils.tryGetMessage(account, replyToMessageId, new TwitterUtils.MessageCallback()
+ {
+ @Override
+ public void success(DirectMessage message)
+ {
+ adapter.addToTop(new MessageViewModel(message, account));
+ adapter.updateForce();
+ }
+
+ @Override
+ public void error()
+ {
+
+ }
+ });
+ }
+ return new AlertDialog.Builder(getActivity()).setView(header).create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void deleteMessage(final Account account, final DirectMessage message)
+ {
+ ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_commands), new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ new DeleteMessageTask(new TwitterApi(account).getTwitter(), message.getId(), getActivity()).execute();
+ dismiss();
+ }
+ });
+ }
+
+ public void openSendMessageDialog(DirectMessage message)
+ {
+ SendMessageDialogFragment dialogFragment = new SendMessageDialogFragment();
+ dialogFragment.setScreenName(message.getSenderScreenName());
+ DialogHelper.showDialog(getActivity(), dialogFragment);
+ }
+
+ private ArrayList<Command> getCommands(Activity activity, DirectMessage message, Account account)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ // URL
+ if(message.getURLEntities() != null)
+ {
+ for(URLEntity urlEntity : message.getURLEntities())
+ {
+ commands.add(new CommandOpenURL(activity, urlEntity.getExpandedURL()));
+ }
+ }
+ for(MediaEntity mediaEntity : getMediaEntities(message))
+ {
+ commands.add(new CommandOpenURL(activity, mediaEntity.getMediaURL()));
+ }
+ return commands;
+ }
+
+ private MediaEntity[] getMediaEntities(DirectMessage message)
+ {
+ if(message.getExtendedMediaEntities().length == 0)
+ {
+ // direct message's media is contained also in url entities.
+ return new MediaEntity[0];
+ }
+ else
+ {
+ return message.getExtendedMediaEntities();
+ }
+ }
+
+ private View getTitleView(MainActivity activity, Account account, DirectMessage message)
+ {
+ View view = activity.getLayoutInflater().inflate(R.layout.dialog_status_detail, null);
+ View messageHeader = view.findViewById(R.id.layout_status_header);
+ MessageViewModel statusViewModel = new MessageViewModel(message, account);
+ messageHeader = statusViewModel.getView(activity, activity.getLayoutInflater(), messageHeader);
+ messageHeader.setClickable(false);
+ int background = ((ColorDrawable) messageHeader.getBackground()).getColor();
+ view.setBackgroundColor(background);
+ ImageButton reply = (ImageButton) view.findViewById(R.id.button_status_detail_reply);
+ reply.setOnClickListener(this);
+ ImageButton delete = (ImageButton) view.findViewById(R.id.button_status_detail_delete);
+ delete.setVisibility(isDeletable(account, message) ? View.VISIBLE : View.GONE);
+ delete.setOnClickListener(this);
+ ImageButton menuButton = (ImageButton) view.findViewById(R.id.button_status_detail_menu);
+ menuButton.setOnClickListener(this);
+ // status only parts
+ view.findViewById(R.id.button_status_detail_retweet).setVisibility(View.GONE);
+ view.findViewById(R.id.button_status_detail_favorite).setVisibility(View.GONE);
+ view.findViewById(R.id.image_status_detail_fav_count).setVisibility(View.GONE);
+ view.findViewById(R.id.image_status_detail_rt_count).setVisibility(View.GONE);
+ return view;
+ }
+
+ private boolean isDeletable(Account account, DirectMessage message)
+ {
+ return message.getSenderId() == account.userID;
+ }
+
+ private void openMenu(MainActivity activity)
+ {
+ MessageMenuDialogFragment fragment = new MessageMenuDialogFragment();
+ fragment.setMessageID(getMessageID());
+ DialogHelper.showDialog(activity, fragment, "messageMenuDialog");
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MessageMenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MessageMenuDialogFragment.java
new file mode 100644
index 00000000..6e375048
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/MessageMenuDialogFragment.java
@@ -0,0 +1,170 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.*;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import net.lacolaco.smileessence.viewmodel.MessageViewModel;
+import twitter4j.DirectMessage;
+import twitter4j.HashtagEntity;
+import twitter4j.MediaEntity;
+import twitter4j.URLEntity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MessageMenuDialogFragment extends MenuDialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final String KEY_MESSAGE_ID = "messageID";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getMessageID()
+ {
+ return getArguments().getLong(KEY_MESSAGE_ID);
+ }
+
+ public void setMessageID(long messageID)
+ {
+ Bundle args = new Bundle();
+ args.putLong(KEY_MESSAGE_ID, messageID);
+ setArguments(args);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ protected void executeCommand(Command command)
+ {
+ if(command.execute())
+ {
+ dismiss();
+ DialogHelper.close(getActivity(), MessageViewModel.DETAIL_DIALOG);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ final CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ listView.setOnItemClickListener(onItemClickListener);
+
+ final AlertDialog alertDialog = new AlertDialog.Builder(activity).setView(body).create();
+ TwitterUtils.tryGetMessage(account, getMessageID(), new TwitterUtils.MessageCallback()
+ {
+ @Override
+ public void success(DirectMessage message)
+ {
+ List<Command> commands = getCommands(activity, message, account);
+ Command.filter(commands);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ }
+
+ @Override
+ public void error()
+ {
+ dismiss();
+ }
+ });
+ return alertDialog;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void addBottomCommands(Activity activity, DirectMessage message, Account account, ArrayList<Command> commands)
+ {
+ commands.add(new CommandSaveAsTemplate(activity, message.getText()));
+ //User
+ for(String screenName : TwitterUtils.getScreenNames(message, null))
+ {
+ commands.add(new CommandOpenUserDetail(activity, screenName, account));
+ }
+ for(Command command : getHashtagCommands(activity, message))
+ {
+ commands.add(command);
+ }
+ // Media
+ if(message.getURLEntities() != null)
+ {
+ for(URLEntity urlEntity : message.getURLEntities())
+ {
+ commands.add(new CommandOpenURL(activity, urlEntity.getExpandedURL()));
+ }
+ }
+ for(MediaEntity mediaEntity : message.getExtendedMediaEntities().length == 0 ? message.getMediaEntities() : message.getExtendedMediaEntities())
+ {
+ commands.add(new CommandOpenURL(activity, mediaEntity.getMediaURL()));
+ }
+ }
+
+ public boolean addMainCommands(Activity activity, DirectMessage message, Account account, ArrayList<Command> commands)
+ {
+ return commands.addAll(Command.getMessageCommands(activity, message, account));
+ }
+
+ public List<Command> getCommands(Activity activity, DirectMessage message, Account account)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ addMainCommands(activity, message, account, commands);
+ addBottomCommands(activity, message, account, commands);
+ return commands;
+ }
+
+ private ArrayList<Command> getHashtagCommands(Activity activity, DirectMessage status)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ if(status.getHashtagEntities() != null)
+ {
+ for(HashtagEntity hashtagEntity : status.getHashtagEntities())
+ {
+ commands.add(new CommandOpenHashtagDialog(activity, hashtagEntity));
+ }
+ }
+ return commands;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/PostMenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/PostMenuDialogFragment.java
new file mode 100644
index 00000000..a9f134a6
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/PostMenuDialogFragment.java
@@ -0,0 +1,104 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandOpenTemplateList;
+import net.lacolaco.smileessence.command.post.PostCommandMakeAnonymous;
+import net.lacolaco.smileessence.command.post.PostCommandMorse;
+import net.lacolaco.smileessence.command.post.PostCommandZekamashi;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PostMenuDialogFragment extends MenuDialogFragment
+{
+
+ public static final String TAG = "postMenu";
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ Account account = activity.getCurrentAccount();
+ List<Command> commands = getCommands(activity);
+ Command.filter(commands);
+ if(commands.isEmpty())
+ {
+ Notificator.publish(getActivity(), R.string.notice_no_command_exists);
+ return new DisposeDialog(getActivity());
+ }
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ listView.setOnItemClickListener(onItemClickListener);
+
+ return new AlertDialog.Builder(activity)
+ .setView(body)
+ .setCancelable(true)
+ .create();
+ }
+
+ @Override
+ protected void executeCommand(Command command)
+ {
+ if(command.execute())
+ {
+ dismiss();
+ DialogHelper.close(getActivity(), TAG);
+ }
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public List<Command> getCommands(Activity activity)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ commands.add(new CommandOpenTemplateList(activity));
+ commands.add(new PostCommandMorse(activity));
+ commands.add(new PostCommandMakeAnonymous(activity));
+ commands.add(new PostCommandZekamashi(activity));
+ return commands;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/QuoteDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/QuoteDialogFragment.java
new file mode 100644
index 00000000..d53a59f1
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/QuoteDialogFragment.java
@@ -0,0 +1,113 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.status.StatusCommandTextQuote;
+import net.lacolaco.smileessence.command.status.StatusCommandURLQuote;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import twitter4j.Status;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class QuoteDialogFragment extends MenuDialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String KEY_STATUS_ID = "statusID";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private long getStatusID()
+ {
+ return getArguments().getLong(KEY_STATUS_ID);
+ }
+
+ public void setStatusID(long id)
+ {
+ Bundle bundle = new Bundle();
+ bundle.putLong(KEY_STATUS_ID, id);
+ setArguments(bundle);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ final CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ listView.setOnItemClickListener(onItemClickListener);
+ Account account = activity.getCurrentAccount();
+ long statusID = getStatusID();
+ TwitterUtils.tryGetStatus(account, statusID, new TwitterUtils.StatusCallback()
+ {
+ @Override
+ public void success(Status status)
+ {
+ List<Command> commands = getCommands(activity, status);
+ Command.filter(commands);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ }
+
+ @Override
+ public void error()
+ {
+ dismiss();
+ }
+ });
+ return new AlertDialog.Builder(activity).setView(body).setCancelable(true).create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public List<Command> getCommands(Activity activity, Status status)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ commands.add(new StatusCommandTextQuote(activity, status));
+ commands.add(new StatusCommandURLQuote(activity, status));
+ return commands;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ReviewDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ReviewDialogFragment.java
new file mode 100644
index 00000000..6adc9124
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/ReviewDialogFragment.java
@@ -0,0 +1,141 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.RatingBar;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.Status;
+
+public class ReviewDialogFragment extends DialogFragment implements View.OnClickListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static String statusIDKey = "key";
+ private long statusID;
+ private RatingBar ratingBar;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public void setStatusID(long statusID)
+ {
+ Bundle args = new Bundle();
+ args.putLong(statusIDKey, statusID);
+ setArguments(args);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(View v)
+ {
+ int id = v.getId();
+ switch(id)
+ {
+ case R.id.button_submit:
+ {
+ execute();
+ break;
+ }
+ }
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ statusID = args.getLong(statusIDKey);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_review, null);
+ ratingBar = (RatingBar) view.findViewById(R.id.rating_review);
+ Button button = (Button) view.findViewById(R.id.button_submit);
+ button.setOnClickListener(this);
+ return new AlertDialog.Builder(getActivity())
+ .setView(view)
+ .create();
+ }
+
+ private void hideIME()
+ {
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(ratingBar.getWindowToken(), 0);
+ }
+
+ private void execute()
+ {
+ hideIME();
+ Status status = StatusCache.getInstance().get(statusID);
+ int star = (int) ratingBar.getRating();
+ StringBuilder builder = new StringBuilder();
+ for(int i = 0; i < 5; i++)
+ {
+ if(i < star)
+ {
+ builder.append("★");
+ }
+ else
+ {
+ builder.append("☆");
+ }
+ }
+ String formatString = getFormatString();
+ String str = String.format(formatString,
+ builder.toString(),
+ TwitterUtils.getOriginalStatus(status).getUser().getScreenName(),
+ TwitterUtils.getStatusURL(status));
+ PostState.newState().beginTransaction()
+ .setText(str)
+ .setInReplyToStatusID(statusID)
+ .setCursor(str.indexOf(":") + 2)
+ .commitWithOpen((MainActivity) getActivity());
+ }
+
+ private String getFormatString()
+ {
+ return getString(R.string.format_status_review);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SearchOnGoogleDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SearchOnGoogleDialogFragment.java
new file mode 100644
index 00000000..c31b5316
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SearchOnGoogleDialogFragment.java
@@ -0,0 +1,146 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.SearchManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import net.lacolaco.smileessence.R;
+
+public class SearchOnGoogleDialogFragment extends DialogFragment implements TextWatcher, View.OnClickListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static String textKey = "key";
+ private String text;
+ private EditText editText;
+ private Button button;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public void setText(String text)
+ {
+ Bundle args = new Bundle();
+ args.putString(textKey, text);
+ setArguments(args);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(View v)
+ {
+ int id = v.getId();
+ switch(id)
+ {
+ case R.id.button_submit:
+ {
+ execute();
+ break;
+ }
+ }
+ }
+
+ // --------------------- Interface TextWatcher ---------------------
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after)
+ {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count)
+ {
+ if(TextUtils.isEmpty(text))
+ {
+ button.setEnabled(false);
+ }
+ else
+ {
+ button.setEnabled(true);
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s)
+ {
+
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ text = args.getString(textKey);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_search_on_google, null);
+ editText = (EditText) view.findViewById(R.id.edittext_search_on_google);
+ editText.addTextChangedListener(this);
+ button = (Button) view.findViewById(R.id.button_submit);
+ button.setOnClickListener(this);
+ editText.setText(text);
+ return new AlertDialog.Builder(getActivity())
+ .setView(view)
+ .create();
+ }
+
+ private void hideIME()
+ {
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
+ }
+
+ private void execute()
+ {
+ hideIME();
+ Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
+ intent.putExtra(SearchManager.QUERY, editText.getText().toString());
+ getActivity().startActivity(intent);
+ DialogHelper.closeAll(getActivity());
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectImageDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectImageDialogFragment.java
new file mode 100644
index 00000000..5b4089b8
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectImageDialogFragment.java
@@ -0,0 +1,143 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.util.IntentUtils;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SelectImageDialogFragment extends MenuDialogFragment
+{
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ Account account = activity.getCurrentAccount();
+ List<Command> commands = getCommands(activity);
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ listView.setOnItemClickListener(onItemClickListener);
+
+ return new AlertDialog.Builder(activity).setView(body).setTitle(R.string.dialog_title_select_image).setCancelable(true).create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public List<Command> getCommands(final MainActivity activity)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ commands.add(new Command(-1, activity)
+ {
+ @Override
+ public boolean execute()
+ {
+ startGallery(activity);
+ return true;
+ }
+
+ @Override
+ public String getText()
+ {
+ return activity.getString(R.string.command_select_image_from_gallery);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+ });
+ commands.add(new Command(-1, activity)
+ {
+ @Override
+ public boolean execute()
+ {
+ startCamera(activity);
+ return true;
+ }
+
+ @Override
+ public String getText()
+ {
+ return activity.getString(R.string.command_select_image_from_camera);
+ }
+
+ @Override
+ public boolean isEnabled()
+ {
+ return true;
+ }
+ });
+ return commands;
+ }
+
+ private void startCamera(MainActivity activity)
+ {
+ ContentValues values = new ContentValues();
+ String filename = System.currentTimeMillis() + ".jpg";
+ values.put(MediaStore.MediaColumns.TITLE, filename);
+ values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
+
+ // Uriを取得して覚えておく、Intentにも保存先として渡す
+ Uri tempFilePath = activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+ activity.setCameraTempFilePath(tempFilePath);
+ Intent intent = new Intent();
+ intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, tempFilePath);
+ IntentUtils.startActivityForResultIfFound(activity, intent, MainActivity.REQUEST_GET_PICTURE_FROM_CAMERA);
+ }
+
+ private void startGallery(MainActivity activity)
+ {
+ Intent intent = new Intent(Intent.ACTION_PICK);
+ intent.setType("image/*");
+ IntentUtils.startActivityForResultIfFound(activity, intent, MainActivity.REQUEST_GET_PICTURE_FROM_GALLERY);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectSearchQueryDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectSearchQueryDialogFragment.java
new file mode 100644
index 00000000..afd40e43
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectSearchQueryDialogFragment.java
@@ -0,0 +1,115 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandOpenSearch;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.entity.SearchQuery;
+import net.lacolaco.smileessence.notification.Notificator;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SelectSearchQueryDialogFragment extends MenuDialogFragment implements AdapterView.OnItemLongClickListener
+{
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnItemLongClickListener ---------------------
+
+ @Override
+ public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
+ {
+ final CommandOpenSearch command = (CommandOpenSearch) parent.getItemAtPosition(position);
+ ConfirmDialogFragment.show(getActivity(), getString(R.string.dialog_confirm_delete_query), new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ deleteQuery(command);
+ }
+ }, false);
+ return true;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ Account account = activity.getCurrentAccount();
+ List<Command> commands = getCommands(activity);
+ Command.filter(commands);
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ listView.setOnItemClickListener(onItemClickListener);
+ listView.setOnItemLongClickListener(this);
+
+ return new AlertDialog.Builder(activity).setView(body).setTitle(R.string.dialog_title_select_search_query).setCancelable(true).create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public List<Command> getCommands(final MainActivity activity)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ final List<SearchQuery> queries = SearchQuery.getAll();
+ if(queries != null)
+ {
+ for(final SearchQuery query : queries)
+ {
+ commands.add(new CommandOpenSearch(activity, query));
+ }
+ }
+ return commands;
+ }
+
+ protected void deleteQuery(CommandOpenSearch command)
+ {
+ command.getQuery().delete();
+ Notificator.publish(getActivity(), R.string.notice_search_query_deleted);
+ ((MainActivity) getActivity()).openSearchPage("");
+ dismiss();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectUserListDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectUserListDialogFragment.java
new file mode 100644
index 00000000..9fdcdf16
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SelectUserListDialogFragment.java
@@ -0,0 +1,84 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandOpenUserList;
+import net.lacolaco.smileessence.data.UserListCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SelectUserListDialogFragment extends MenuDialogFragment
+{
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ Account account = activity.getCurrentAccount();
+ List<Command> commands = getCommands(activity);
+ Command.filter(commands);
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ listView.setOnItemClickListener(onItemClickListener);
+
+ return new AlertDialog.Builder(activity).setView(body).setTitle(R.string.dialog_title_select_userlist).setCancelable(true).create();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public List<Command> getCommands(final MainActivity activity)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ final String[] lists = UserListCache.getInstance().getAll();
+ if(lists != null)
+ {
+ for(final String list : lists)
+ {
+ commands.add(new CommandOpenUserList(activity, list));
+ }
+ }
+ return commands;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SendMessageDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SendMessageDialogFragment.java
new file mode 100644
index 00000000..d765765d
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SendMessageDialogFragment.java
@@ -0,0 +1,182 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.TextView;
+import com.twitter.Validator;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.SendMessageTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import twitter4j.Twitter;
+
+public class SendMessageDialogFragment extends DialogFragment implements TextWatcher, View.OnClickListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static String screenNameKey = "screenName";
+ private String screenName;
+ private EditText editText;
+ private TextView textViewCount;
+ private Button buttonSend;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public void setScreenName(String screenName)
+ {
+ Bundle args = new Bundle();
+ args.putString(screenNameKey, screenName);
+ setArguments(args);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(View v)
+ {
+ int id = v.getId();
+ switch(id)
+ {
+ case R.id.button_send_message:
+ {
+ sendMessage();
+ break;
+ }
+ case R.id.button_send_message_delete:
+ {
+ deleteMessage();
+ }
+ }
+ }
+
+ // --------------------- Interface TextWatcher ---------------------
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after)
+ {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count)
+ {
+ int remainingCount = 140 - TwitterUtils.getFixedTextLength(s.toString());
+ if(!TextUtils.isEmpty(PostState.getState().getMediaFilePath()))
+ {
+ remainingCount -= new Validator().getShortUrlLength();
+ }
+ textViewCount.setText(String.valueOf(remainingCount));
+ if(remainingCount == 140)
+ {
+ textViewCount.setTextColor(getResources().getColor(R.color.red));
+ buttonSend.setEnabled(false);
+ }
+ else if(remainingCount < 0)
+ {
+ textViewCount.setTextColor(getResources().getColor(R.color.red));
+ buttonSend.setEnabled(false);
+ }
+ else
+ {
+ textViewCount.setTextAppearance(getActivity(), android.R.style.TextAppearance_Widget_TextView);
+ buttonSend.setEnabled(true);
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable s)
+ {
+
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ screenName = args.getString(screenNameKey);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_send_message, null);
+ TextView textViewName = (TextView) view.findViewById(R.id.textview_send_message_name);
+ textViewName.setText("To: @" + screenName);
+ textViewCount = (TextView) view.findViewById(R.id.textview_send_message_count);
+ editText = (EditText) view.findViewById(R.id.edittext_send_message);
+ editText.addTextChangedListener(this);
+ buttonSend = (Button) view.findViewById(R.id.button_send_message);
+ buttonSend.setOnClickListener(this);
+ ImageButton buttonDelete = (ImageButton) view.findViewById(R.id.button_send_message_delete);
+ buttonDelete.setOnClickListener(this);
+ editText.setText("");
+ return new AlertDialog.Builder(getActivity())
+ .setView(view)
+ .create();
+ }
+
+ private void deleteMessage()
+ {
+ editText.setText("");
+ }
+
+ private void hideIME()
+ {
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
+ }
+
+ private void sendMessage()
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ Twitter twitter = TwitterApi.getTwitter(activity.getCurrentAccount());
+ String text = editText.getText().toString();
+ new SendMessageTask(twitter, screenName, text, activity).execute();
+ hideIME();
+ dismiss();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SimpleDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SimpleDialogFragment.java
new file mode 100644
index 00000000..ec10e70c
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/SimpleDialogFragment.java
@@ -0,0 +1,88 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import net.lacolaco.smileessence.R;
+
+public class SimpleDialogFragment extends DialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String ARG_LAYOUT = "layout";
+ public static final String ARG_TITLE = "title";
+ private int layoutResourceID;
+ private String title;
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static SimpleDialogFragment newInstance(int layoutResourceID, String title)
+ {
+ SimpleDialogFragment fragment = new SimpleDialogFragment();
+ Bundle args = new Bundle();
+ args.putInt(ARG_LAYOUT, layoutResourceID);
+ args.putString(ARG_TITLE, title);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ layoutResourceID = args.getInt(ARG_LAYOUT);
+ title = args.getString(ARG_TITLE);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View contentView = inflater.inflate(layoutResourceID, null);
+
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(title)
+ .setView(contentView)
+ .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which)
+ {
+ dialog.dismiss();
+ }
+ })
+ .create();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/StatusDetailDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/StatusDetailDialogFragment.java
new file mode 100644
index 00000000..8c74edce
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/StatusDetailDialogFragment.java
@@ -0,0 +1,392 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.*;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandOpenURL;
+import net.lacolaco.smileessence.command.status.StatusCommandReplyToAll;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.TweetBuilder;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.DeleteStatusTask;
+import net.lacolaco.smileessence.twitter.task.FavoriteTask;
+import net.lacolaco.smileessence.twitter.task.RetweetTask;
+import net.lacolaco.smileessence.twitter.task.UnfavoriteTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.PostState;
+import net.lacolaco.smileessence.view.adapter.StatusListAdapter;
+import net.lacolaco.smileessence.view.listener.ListItemClickListener;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.MediaEntity;
+import twitter4j.Status;
+import twitter4j.URLEntity;
+import twitter4j.User;
+
+import java.util.ArrayList;
+
+public class StatusDetailDialogFragment extends DialogFragment implements View.OnClickListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final String KEY_STATUS_ID = "statusID";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getStatusID()
+ {
+ return getArguments().getLong(KEY_STATUS_ID);
+ }
+
+ public void setStatusID(long statusID)
+ {
+ Bundle args = new Bundle();
+ args.putLong(KEY_STATUS_ID, statusID);
+ setArguments(args);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(final View v)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+ TwitterUtils.tryGetStatus(account, getStatusID(), new TwitterUtils.StatusCallback()
+ {
+ @Override
+ public void success(Status status)
+ {
+ switch(v.getId())
+ {
+ case R.id.button_status_detail_reply:
+ {
+ replyToStatus(activity, status);
+ break;
+ }
+ case R.id.button_status_detail_retweet:
+ {
+ final Long retweetID = (Long) v.getTag();
+ toggleRetweet(activity, account, status, retweetID);
+ break;
+ }
+ case R.id.button_status_detail_favorite:
+ {
+ Boolean isFavorited = (Boolean) v.getTag();
+ toggleFavorite(activity, account, status, isFavorited);
+ break;
+ }
+ case R.id.button_status_detail_delete:
+ {
+ deleteStatus(activity, account, status);
+ break;
+ }
+ case R.id.button_status_detail_menu:
+ {
+ openMenu(activity);
+ break;
+ }
+ default:
+ {
+ dismiss();
+ }
+ }
+ }
+
+ @Override
+ public void error()
+ {
+
+ }
+ });
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+
+ Status status = StatusCache.getInstance().get(getStatusID());
+ View header = getTitleView(activity, account, status);
+ ListView listView = (ListView) header.findViewById(R.id.listview_status_detail_reply_to);
+ final StatusListAdapter adapter = new StatusListAdapter(getActivity());
+ listView.setAdapter(adapter);
+ long inReplyToStatusId = TwitterUtils.getOriginalStatus(status).getInReplyToStatusId();
+ if(inReplyToStatusId == -1)
+ {
+ listView.setVisibility(View.GONE);
+ }
+ else
+ {
+ TwitterUtils.tryGetStatus(account, inReplyToStatusId, new TwitterUtils.StatusCallback()
+ {
+ @Override
+ public void success(Status status)
+ {
+ adapter.addToTop(new StatusViewModel(status, account));
+ adapter.updateForce();
+ }
+
+ @Override
+ public void error()
+ {
+
+ }
+ });
+ }
+ return new AlertDialog.Builder(getActivity()).setView(header).create();
+ }
+
+ private void confirm(MainActivity activity, Runnable onYes)
+ {
+ ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands), onYes);
+ }
+
+ private void deleteStatus(final MainActivity activity, final Account account, final Status status)
+ {
+ confirm(activity, new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ new DeleteStatusTask(TwitterApi.getTwitter(account), TwitterUtils.getOriginalStatus(status).getId(), activity).execute();
+ dismiss();
+ }
+ });
+ }
+
+ private View getTitleView(MainActivity activity, Account account, Status status)
+ {
+ View view = activity.getLayoutInflater().inflate(R.layout.dialog_status_detail, null);
+ View statusHeader = view.findViewById(R.id.layout_status_header);
+ StatusViewModel statusViewModel = new StatusViewModel(status, account);
+ statusHeader = statusViewModel.getView(activity, activity.getLayoutInflater(), statusHeader);
+ statusHeader.setClickable(false);
+ int background = ((ColorDrawable) statusHeader.getBackground()).getColor();
+ view.setBackgroundColor(background);
+ ImageView favCountIcon = (ImageView) view.findViewById(R.id.image_status_detail_fav_count);
+ ImageView rtCountIcon = (ImageView) view.findViewById(R.id.image_status_detail_rt_count);
+ TextView favCountText = (TextView) view.findViewById(R.id.textview_status_detail_fav_count);
+ TextView rtCountText = (TextView) view.findViewById(R.id.textview_status_detail_rt_count);
+ int favoriteCount = TwitterUtils.getOriginalStatus(status).getFavoriteCount();
+ if(favoriteCount == 0)
+ {
+ favCountIcon.setVisibility(View.GONE);
+ favCountText.setVisibility(View.GONE);
+ }
+ else
+ {
+ favCountText.setText(Integer.toString(favoriteCount));
+ }
+ int retweetCount = TwitterUtils.getOriginalStatus(status).getRetweetCount();
+ if(retweetCount == 0)
+ {
+ rtCountIcon.setVisibility(View.GONE);
+ rtCountText.setVisibility(View.GONE);
+ }
+ else
+ {
+ rtCountText.setText(Integer.toString(retweetCount));
+ }
+ ImageButton menu = (ImageButton) view.findViewById(R.id.button_status_detail_menu);
+ ImageButton message = (ImageButton) view.findViewById(R.id.button_status_detail_reply);
+ ImageButton retweet = (ImageButton) view.findViewById(R.id.button_status_detail_retweet);
+ ImageButton favorite = (ImageButton) view.findViewById(R.id.button_status_detail_favorite);
+ ImageButton delete = (ImageButton) view.findViewById(R.id.button_status_detail_delete);
+ menu.setOnClickListener(this);
+ message.setOnClickListener(this);
+ retweet.setOnClickListener(this);
+ favorite.setOnClickListener(this);
+ delete.setOnClickListener(this);
+ if(isNotRetweetable(account, status))
+ {
+ retweet.setVisibility(View.GONE);
+ }
+ else if(isRetweetDeletable(account, status))
+ {
+ retweet.setImageDrawable(getResources().getDrawable(R.drawable.icon_retweet_on));
+ retweet.setTag(status.getId());
+ }
+ else
+ {
+ retweet.setTag(-1L);
+ }
+ favorite.setTag(statusViewModel.isFavorited());
+ if(statusViewModel.isFavorited())
+ {
+ favorite.setImageDrawable(getResources().getDrawable(R.drawable.icon_favorite_on));
+ }
+ boolean deletable = isDeletable(account, status);
+ delete.setVisibility(deletable ? View.VISIBLE : View.GONE);
+ LinearLayout commandsLayout = (LinearLayout) view.findViewById(R.id.linearlayout_status_detail_menu);
+ commandsLayout.setClickable(true);
+ ArrayList<Command> commands = getCommands(activity, status, account);
+ Command.filter(commands);
+ for(final Command command : commands)
+ {
+ View commandView = command.getView(activity, activity.getLayoutInflater(), null);
+ commandView.setBackgroundColor(getResources().getColor(R.color.transparent));
+ commandView.setOnClickListener(new ListItemClickListener(activity, new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ command.execute();
+ dismiss();
+ }
+ }));
+ commandsLayout.addView(commandView);
+ }
+ return view;
+ }
+
+
+ private MediaEntity[] getMediaEntities(Status status)
+ {
+ if(status.getExtendedMediaEntities().length == 0)
+ {
+ return status.getMediaEntities();
+ }
+ else
+ {
+ return status.getExtendedMediaEntities();
+ }
+ }
+
+ private ArrayList<Command> getCommands(Activity activity, Status status, Account account)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ // URL
+ if(status.getURLEntities() != null)
+ {
+ for(URLEntity urlEntity : status.getURLEntities())
+ {
+ commands.add(new CommandOpenURL(activity, urlEntity.getExpandedURL()));
+ }
+ }
+ for(MediaEntity mediaEntity : getMediaEntities(status))
+ {
+ commands.add(new CommandOpenURL(activity, mediaEntity.getMediaURL()));
+ }
+ // ReplyToAll
+ commands.add(new StatusCommandReplyToAll(activity, status, account));
+ return commands;
+ }
+
+ private boolean isDeletable(Account account, Status status)
+ {
+ boolean deletable;
+ if(!status.isRetweet())
+ {
+ deletable = status.getUser().getId() == account.userID;
+ }
+ else
+ {
+ deletable = status.getRetweetedStatus().getUser().getId() == account.userID;
+ }
+ return deletable;
+ }
+
+ private boolean isNotRetweetable(Account account, Status status)
+ {
+ User user = TwitterUtils.getOriginalStatus(status).getUser();
+ return user.isProtected() || user.getId() == account.userID;
+ }
+
+ private boolean isRetweetDeletable(Account account, Status status)
+ {
+ return status.isRetweet() && status.getUser().getId() == account.userID;
+ }
+
+ private void openMenu(MainActivity activity)
+ {
+ StatusMenuDialogFragment fragment = new StatusMenuDialogFragment();
+ fragment.setStatusID(getStatusID());
+ DialogHelper.showDialog(activity, fragment, "statusMenuDialog");
+ }
+
+ private void replyToStatus(MainActivity activity, Status status)
+ {
+ Status originalStatus = TwitterUtils.getOriginalStatus(status);
+ TweetBuilder builder = new TweetBuilder().addScreenName(originalStatus.getUser().getScreenName());
+ String text = builder.buildText();
+ PostState.newState().beginTransaction()
+ .setText(text)
+ .setInReplyToStatusID(originalStatus.getId())
+ .moveCursor(text.length())
+ .commitWithOpen(activity);
+ }
+
+ private void toggleFavorite(MainActivity activity, Account account, Status status, Boolean isFavorited)
+ {
+ long statusID = status.isRetweet() ? status.getRetweetedStatus().getId() : status.getId();
+ if(isFavorited)
+ {
+ new UnfavoriteTask(TwitterApi.getTwitter(account), statusID, activity).execute();
+ }
+ else
+ {
+ new FavoriteTask(TwitterApi.getTwitter(account), statusID, activity).execute();
+ }
+ dismiss();
+ }
+
+ private void toggleRetweet(final MainActivity activity, final Account account, final Status status, final Long retweetID)
+ {
+ confirm(activity, new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ if(retweetID != -1L)
+ {
+ new DeleteStatusTask(TwitterApi.getTwitter(account), retweetID, activity).execute();
+ }
+ else
+ {
+ new RetweetTask(TwitterApi.getTwitter(account), TwitterUtils.getOriginalStatus(status).getId(), activity).execute();
+ }
+ dismiss();
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/StatusMenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/StatusMenuDialogFragment.java
new file mode 100644
index 00000000..a284b10e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/StatusMenuDialogFragment.java
@@ -0,0 +1,171 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.*;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.HashtagEntity;
+import twitter4j.MediaEntity;
+import twitter4j.Status;
+import twitter4j.URLEntity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StatusMenuDialogFragment extends MenuDialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final String KEY_STATUS_ID = "statusID";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getStatusID()
+ {
+ return getArguments().getLong(KEY_STATUS_ID);
+ }
+
+ public void setStatusID(long statusID)
+ {
+ Bundle args = new Bundle();
+ args.putLong(KEY_STATUS_ID, statusID);
+ setArguments(args);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+
+ @Override
+ protected void executeCommand(Command command)
+ {
+ if(command.execute())
+ {
+ dismiss();
+ DialogHelper.close(getActivity(), StatusViewModel.STATUS_DIALOG);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ final CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ listView.setOnItemClickListener(onItemClickListener);
+
+ final AlertDialog alertDialog = new AlertDialog.Builder(activity).setView(body).create();
+ TwitterUtils.tryGetStatus(account, getStatusID(), new TwitterUtils.StatusCallback()
+ {
+ @Override
+ public void success(Status status)
+ {
+ List<Command> commands = getCommands(activity, status, account);
+ Command.filter(commands);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ }
+
+ @Override
+ public void error()
+ {
+ dismiss();
+ }
+ });
+ return alertDialog;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public void addBottomCommands(Activity activity, Status status, Account account, ArrayList<Command> commands)
+ {
+ commands.add(new CommandSaveAsTemplate(activity, TwitterUtils.getOriginalStatusText(status)));
+ //User
+ for(String screenName : TwitterUtils.getScreenNames(status, null))
+ {
+ commands.add(new CommandOpenUserDetail(activity, screenName, account));
+ }
+ for(Command command : getHashtagCommands(activity, status))
+ {
+ commands.add(command);
+ }
+ // Media
+ if(status.getURLEntities() != null)
+ {
+ for(URLEntity urlEntity : status.getURLEntities())
+ {
+ commands.add(new CommandOpenURL(activity, urlEntity.getExpandedURL()));
+ }
+ }
+ for(MediaEntity mediaEntity : status.getExtendedMediaEntities().length == 0 ? status.getMediaEntities() : status.getExtendedMediaEntities())
+ {
+ commands.add(new CommandOpenURL(activity, mediaEntity.getMediaURL()));
+ }
+ }
+
+ public boolean addMainCommands(Activity activity, Status status, Account account, ArrayList<Command> commands)
+ {
+ return commands.addAll(Command.getStatusCommands(activity, status, account));
+ }
+
+ public List<Command> getCommands(Activity activity, Status status, Account account)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ addMainCommands(activity, status, account, commands);
+ addBottomCommands(activity, status, account, commands);
+ return commands;
+ }
+
+ private ArrayList<Command> getHashtagCommands(Activity activity, Status status)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ if(status.getHashtagEntities() != null)
+ {
+ for(HashtagEntity hashtagEntity : status.getHashtagEntities())
+ {
+ commands.add(new CommandOpenHashtagDialog(activity, hashtagEntity));
+ }
+ }
+ return commands;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/TalkChainDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/TalkChainDialogFragment.java
new file mode 100644
index 00000000..bfed7d81
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/TalkChainDialogFragment.java
@@ -0,0 +1,153 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.StatusCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.StatusListAdapter;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterException;
+
+public class TalkChainDialogFragment extends DialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String KEY_STATUS_ID = "statusID";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ private long getStatusID()
+ {
+ return getArguments().getLong(KEY_STATUS_ID);
+ }
+
+ public void setStatusID(long id)
+ {
+ Bundle bundle = new Bundle();
+ bundle.putLong(KEY_STATUS_ID, id);
+ setArguments(bundle);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+
+ View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_talk_list, null);
+ ListView listView = (ListView) view.findViewById(R.id.listview_dialog_talk_list);
+ final StatusListAdapter adapter = new StatusListAdapter(getActivity());
+ listView.setAdapter(adapter);
+ TwitterUtils.tryGetStatus(account, getStatusID(), new TwitterUtils.StatusCallback()
+ {
+ @Override
+ public void success(Status status)
+ {
+ adapter.addToTop(new StatusViewModel(status, account));
+ adapter.updateForce();
+ Twitter twitter = TwitterApi.getTwitter(account);
+ new GetTalkTask(twitter, account, adapter, status.getInReplyToStatusId()).execute();
+ }
+
+ @Override
+ public void error()
+ {
+ dismiss();
+ }
+ });
+
+ return new AlertDialog.Builder(activity)
+ .setTitle(R.string.dialog_title_talk_chain)
+ .setView(view)
+ .setCancelable(true)
+ .create();
+ }
+
+ // -------------------------- INNER CLASSES --------------------------
+
+ private class GetTalkTask extends AsyncTask<Void, Void, Void>
+ {
+
+ private final Twitter twitter;
+ private final Account account;
+ private final StatusListAdapter adapter;
+ private final long inReplyToStatusId;
+
+ public GetTalkTask(Twitter twitter, Account account, StatusListAdapter adapter, long inReplyToStatusId)
+ {
+ this.twitter = twitter;
+ this.account = account;
+ this.adapter = adapter;
+ this.inReplyToStatusId = inReplyToStatusId;
+ }
+
+ @Override
+ protected Void doInBackground(Void... params)
+ {
+ try
+ {
+ long id = inReplyToStatusId;
+ while(id != -1)
+ {
+ final twitter4j.Status status = twitter.showStatus(id);
+ if(status != null)
+ {
+ StatusCache.getInstance().put(status);
+ adapter.addToBottom(new StatusViewModel(status, account));
+ adapter.updateForce();
+ id = status.getInReplyToStatusId();
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ catch(TwitterException e)
+ {
+ e.printStackTrace();
+ Logger.error(e);
+ }
+ return null;
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/UserDetailDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/UserDetailDialogFragment.java
new file mode 100644
index 00000000..f36fa059
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/UserDetailDialogFragment.java
@@ -0,0 +1,527 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.view.View;
+import android.widget.*;
+import com.android.volley.toolbox.NetworkImageView;
+import com.handmark.pulltorefresh.library.PullToRefreshBase;
+import com.handmark.pulltorefresh.library.PullToRefreshListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandOpenURL;
+import net.lacolaco.smileessence.data.ImageCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.logging.Logger;
+import net.lacolaco.smileessence.twitter.TwitterApi;
+import net.lacolaco.smileessence.twitter.task.FollowTask;
+import net.lacolaco.smileessence.twitter.task.ShowFriendshipTask;
+import net.lacolaco.smileessence.twitter.task.UnfollowTask;
+import net.lacolaco.smileessence.twitter.task.UserTimelineTask;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.Themes;
+import net.lacolaco.smileessence.util.UIHandler;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import net.lacolaco.smileessence.view.adapter.StatusListAdapter;
+import net.lacolaco.smileessence.viewmodel.StatusViewModel;
+import twitter4j.Paging;
+import twitter4j.Relationship;
+import twitter4j.Twitter;
+import twitter4j.User;
+
+public class UserDetailDialogFragment extends DialogFragment implements View.OnClickListener,
+ PullToRefreshBase.OnRefreshListener2<ListView>
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String USER_MENU_DIALOG = "userMenuDialog";
+ private static final String KEY_USER_ID = "userID";
+ private static final int ADAPTER_INDEX = 100;
+ private TextView textViewScreenName;
+ private TextView textViewName;
+ private TextView textViewURL;
+ private TextView textViewLocate;
+ private TextView textViewFollowed;
+ private TextView textViewProtected;
+ private TextView textViewDescription;
+ private TextView textViewTweetCount;
+ private TextView textViewFriendCount;
+ private TextView textViewFollowerCount;
+ private TextView textViewFavoriteCount;
+ private NetworkImageView imageViewIcon;
+ private NetworkImageView imageViewHeader;
+ private Button buttonFollow;
+ private PullToRefreshListView listViewTimeline;
+ private TabHost tabHost;
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getUserID()
+ {
+ return getArguments().getLong(KEY_USER_ID);
+ }
+
+ public void setUserID(long userID)
+ {
+ Bundle args = new Bundle();
+ args.putLong(KEY_USER_ID, userID);
+ setArguments(args);
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(final View v)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+ TwitterUtils.tryGetUser(account, getUserID(), new TwitterUtils.UserCallback()
+ {
+ @Override
+ public void success(final User user)
+ {
+ switch(v.getId())
+ {
+ case R.id.imageview_user_detail_menu:
+ {
+ openUserMenu(activity, user);
+ break;
+ }
+ case R.id.imageview_user_detail_icon:
+ {
+ openUrl(user.getBiggerProfileImageURLHttps());
+ break;
+ }
+ case R.id.textview_user_detail_screenname:
+ {
+ openUrl(TwitterUtils.getUserHomeURL(user.getScreenName()));
+ break;
+ }
+ case R.id.textview_user_detail_tweet_count:
+ {
+ openUrl(TwitterUtils.getUserHomeURL(user.getScreenName()));
+ break;
+ }
+ case R.id.textview_user_detail_friend_count:
+ {
+ openUrl(String.format("%s/following", TwitterUtils.getUserHomeURL(user.getScreenName())));
+ break;
+ }
+ case R.id.textview_user_detail_follower_count:
+ {
+ openUrl(String.format("%s/followers", TwitterUtils.getUserHomeURL(user.getScreenName())));
+ break;
+ }
+ case R.id.textview_user_detail_favorite_count:
+ {
+ openUrl(String.format("%s/favorites", TwitterUtils.getUserHomeURL(user.getScreenName())));
+ break;
+ }
+ case R.id.button_user_detail_follow:
+ {
+ ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands), new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ toggleFollowing(user, account, activity);
+ }
+ });
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void error()
+ {
+ dismiss();
+ }
+ });
+ }
+
+ // --------------------- Interface OnRefreshListener2 ---------------------
+
+ @Override
+ public void onPullDownToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final StatusListAdapter adapter = getListAdapter(activity);
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setSinceId(adapter.getTopID());
+ }
+ new UserTimelineTask(twitter, getUserID(), paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(int i = statuses.length - 1; i >= 0; i--)
+ {
+ twitter4j.Status status = statuses[i];
+ adapter.addToTop(new StatusViewModel(status, currentAccount));
+ }
+ updateListView(refreshView.getRefreshableView(), adapter, true);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onPullUpToRefresh(final PullToRefreshBase<ListView> refreshView)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account currentAccount = activity.getCurrentAccount();
+ Twitter twitter = TwitterApi.getTwitter(currentAccount);
+ final StatusListAdapter adapter = getListAdapter(activity);
+ Paging paging = TwitterUtils.getPaging(TwitterUtils.getPagingCount(activity));
+ if(adapter.getCount() > 0)
+ {
+ paging.setMaxId(adapter.getLastID() - 1);
+ }
+ new UserTimelineTask(twitter, getUserID(), paging)
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(twitter4j.Status status : statuses)
+ {
+ adapter.addToBottom(new StatusViewModel(status, currentAccount));
+ }
+ updateListView(refreshView.getRefreshableView(), adapter, false);
+ refreshView.onRefreshComplete();
+ }
+ }.execute();
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ MainActivity activity = (MainActivity) getActivity();
+ View v = activity.getLayoutInflater().inflate(R.layout.dialog_user_detail, null);
+ View menu = v.findViewById(R.id.imageview_user_detail_menu);
+ menu.setOnClickListener(this);
+ textViewScreenName = (TextView) v.findViewById(R.id.textview_user_detail_screenname);
+ textViewScreenName.setOnClickListener(this);
+ textViewName = (TextView) v.findViewById(R.id.textview_user_detail_name);
+ textViewURL = (TextView) v.findViewById(R.id.textview_user_detail_url);
+ textViewLocate = (TextView) v.findViewById(R.id.textview_user_detail_locate);
+ textViewFollowed = (TextView) v.findViewById(R.id.textview_user_detail_followed);
+ textViewProtected = (TextView) v.findViewById(R.id.texttview_user_detail_protected);
+ textViewDescription = (TextView) v.findViewById(R.id.textview_user_detail_description);
+ textViewTweetCount = (TextView) v.findViewById(R.id.textview_user_detail_tweet_count);
+ textViewTweetCount.setOnClickListener(this);
+ textViewFriendCount = (TextView) v.findViewById(R.id.textview_user_detail_friend_count);
+ textViewFriendCount.setOnClickListener(this);
+ textViewFollowerCount = (TextView) v.findViewById(R.id.textview_user_detail_follower_count);
+ textViewFollowerCount.setOnClickListener(this);
+ textViewFavoriteCount = (TextView) v.findViewById(R.id.textview_user_detail_favorite_count);
+ textViewFavoriteCount.setOnClickListener(this);
+ imageViewIcon = (NetworkImageView) v.findViewById(R.id.imageview_user_detail_icon);
+ imageViewIcon.setOnClickListener(this);
+ imageViewHeader = (NetworkImageView) v.findViewById(R.id.imageview_user_detail_header);
+ buttonFollow = (Button) v.findViewById(R.id.button_user_detail_follow);
+ buttonFollow.setOnClickListener(this);
+ listViewTimeline = (PullToRefreshListView) v.findViewById(R.id.listview_user_detail_timeline);
+
+ tabHost = (TabHost) v.findViewById(android.R.id.tabhost);
+ tabHost.setup();
+ TabHost.TabSpec tab1 = tabHost.newTabSpec("tab1").setContent(R.id.tab1).setIndicator(getString(R.string.user_detail_tab_info));
+ tabHost.addTab(tab1);
+ TabHost.TabSpec tab2 = tabHost.newTabSpec("tab2").setContent(R.id.tab2).setIndicator(getString(R.string.user_detail_tab_timeline));
+ tabHost.addTab(tab2);
+ tabHost.setCurrentTab(0);
+
+ final Account account = activity.getCurrentAccount();
+ TwitterUtils.tryGetUser(account, getUserID(), new TwitterUtils.UserCallback()
+ {
+ @Override
+ public void success(User user)
+ {
+ try
+ {
+ initUserData(user, account);
+ }
+ catch(Exception e)
+ {
+ Logger.error(e);
+ error();
+ }
+ }
+
+ @Override
+ public void error()
+ {
+ dismiss();
+ }
+ });
+ return new AlertDialog.Builder(activity)
+ .setView(v)
+ .setCancelable(true)
+ .create();
+ }
+
+ private void executeUserTimelineTask(final User user, final Account account, final StatusListAdapter adapter)
+ {
+ tabHost.getTabWidget().getChildTabViewAt(1).setVisibility(View.GONE);
+ Twitter twitter = TwitterApi.getTwitter(account);
+ new UserTimelineTask(twitter, user.getId())
+ {
+ @Override
+ protected void onPostExecute(twitter4j.Status[] statuses)
+ {
+ super.onPostExecute(statuses);
+ for(twitter4j.Status status : statuses)
+ {
+ adapter.addToBottom(new StatusViewModel(status, account));
+ }
+ adapter.updateForce();
+ tabHost.getTabWidget().getChildTabViewAt(1).setVisibility(View.VISIBLE);
+ }
+ }.execute();
+ }
+
+ private String getHtmlDescription(String description)
+ {
+ if(TextUtils.isEmpty(description))
+ {
+ return "";
+ }
+ String html = description;
+ html = html.replaceAll("https?://[\\w/:%#\\$&\\?\\(\\)~\\.=\\+\\-]+", "<a href=\"$0\">$0</a>");
+ html = html.replaceAll("@([a-zA-Z0-9_]+)", "<a href=\"" + TwitterUtils.getUserHomeURL("$1") + "\">$0</a>");
+ html = html.replaceAll("\r\n", "<br />");
+ return html;
+ }
+
+ private StatusListAdapter getListAdapter(MainActivity activity)
+ {
+ return (StatusListAdapter) activity.getListAdapter(ADAPTER_INDEX);
+ }
+
+ private void initUserData(User user, final Account account)
+ {
+ textViewName.setText(user.getName());
+ textViewScreenName.setText(user.getScreenName());
+ if(TextUtils.isEmpty(user.getLocation()))
+ {
+ textViewLocate.setVisibility(View.GONE);
+ }
+ else
+ {
+ textViewLocate.setText(user.getLocation());
+ }
+ if(TextUtils.isEmpty(user.getURL()))
+ {
+ textViewURL.setVisibility(View.GONE);
+ }
+ else
+ {
+ textViewURL.setText(user.getURL());
+ }
+ textViewTweetCount.setText(String.valueOf(user.getStatusesCount()));
+ textViewFriendCount.setText(String.valueOf(user.getFriendsCount()));
+ textViewFollowerCount.setText(String.valueOf(user.getFollowersCount()));
+ textViewFavoriteCount.setText(String.valueOf(user.getFavouritesCount()));
+ textViewProtected.setVisibility(user.isProtected() ? View.VISIBLE : View.GONE);
+ String htmlDescription = getHtmlDescription(user.getDescription());
+ textViewDescription.setText(Html.fromHtml(htmlDescription));
+ textViewDescription.setMovementMethod(LinkMovementMethod.getInstance());
+ ImageCache.getInstance().setImageToView(user.getBiggerProfileImageURL(), imageViewIcon);
+ ImageCache.getInstance().setImageToView(user.getProfileBannerURL(), imageViewHeader);
+ MainActivity activity = (MainActivity) getActivity();
+ final StatusListAdapter adapter = new StatusListAdapter(activity);
+ listViewTimeline.setAdapter(adapter);
+ listViewTimeline.setOnRefreshListener(this);
+ activity.setListAdapter(ADAPTER_INDEX, adapter);
+ executeUserTimelineTask(user, account, adapter);
+ updateRelationship(activity, user.getId());
+ }
+
+ private void lockFollowButton(Activity activity)
+ {
+ buttonFollow.setText(R.string.user_detail_loading);
+ buttonFollow.setBackground(activity.getResources().getDrawable(R.drawable.button_round_gray));
+ buttonFollow.setEnabled(false);
+ }
+
+ private void openUrl(String url)
+ {
+ new CommandOpenURL(getActivity(), url).execute();
+ }
+
+ private void openUserMenu(final MainActivity activity, final User user)
+ {
+ UserMenuDialogFragment menuFragment = new UserMenuDialogFragment()
+ {
+ @Override
+ protected void executeCommand(Command command)
+ {
+ super.executeCommand(command);
+ new UIHandler()
+ {
+ @Override
+ public void run()
+ {
+ if(UserDetailDialogFragment.this.isDetached())
+ {
+ return;
+ }
+ updateRelationship(activity, user.getId());
+ }
+ }.postDelayed(1000);
+ }
+ };
+ menuFragment.setUserID(user.getId());
+ DialogHelper.showDialog(activity, menuFragment, USER_MENU_DIALOG);
+ }
+
+ private void setFollowButtonState(boolean isFollowing, Drawable unfollowColor, Drawable followColor)
+ {
+ buttonFollow.setText(isFollowing ? R.string.user_detail_unfollow : R.string.user_detail_follow);
+ buttonFollow.setBackground(isFollowing ? unfollowColor : followColor);
+ buttonFollow.setTag(isFollowing);
+ buttonFollow.setEnabled(true);
+ }
+
+ private void toggleFollowing(final User user, final Account account, final Activity activity)
+ {
+ lockFollowButton(activity);
+ Boolean isFollowing = buttonFollow.getTag() != null ? (Boolean) buttonFollow.getTag() : false;
+ Twitter twitter = new TwitterApi(account).getTwitter();
+ if(isFollowing)
+ {
+ new UnfollowTask(twitter, user.getId(), activity)
+ {
+ @Override
+ public void onPostExecute(User result)
+ {
+ super.onPostExecute(result);
+ updateRelationship(activity, user.getId());
+ buttonFollow.setEnabled(true);
+ }
+ }.execute();
+ }
+ else
+ {
+ new FollowTask(twitter, user.getId(), activity)
+ {
+ @Override
+ public void onPostExecute(User result)
+ {
+ super.onPostExecute(result);
+ updateRelationship(activity, user.getId());
+ buttonFollow.setEnabled(true);
+ }
+ }.execute();
+ }
+ }
+
+ protected void updateListView(AbsListView absListView, CustomListAdapter<?> adapter, boolean addedToTop)
+ {
+ int before = adapter.getCount();
+ adapter.notifyDataSetChanged(); // synchronized call (not adapter#updateForce())
+ int after = adapter.getCount();
+ int increments = after - before;
+ if(increments > 0)
+ {
+ adapter.setNotifiable(false);
+ if(addedToTop)
+ {
+ absListView.setSelection(increments + 1);
+ absListView.smoothScrollToPositionFromTop(increments, 0);
+ absListView.setSelection(increments);
+ }
+ else
+ {
+ absListView.smoothScrollToPositionFromTop(before, 0);
+ }
+
+ if(increments == 1)
+ {
+ adapter.setNotifiable(true);
+ }
+ }
+ else
+ {
+ adapter.setNotifiable(true);
+ }
+ }
+
+ private void updateRelationship(Activity activity, final long userId)
+ {
+ MainActivity mainActivity = (MainActivity) activity;
+ Account account = mainActivity.getCurrentAccount();
+ Twitter twitter = new TwitterApi(account).getTwitter();
+ if(userId == account.userID)
+ {
+ textViewFollowed.setText(R.string.user_detail_followed_is_me);
+ buttonFollow.setVisibility(View.GONE);
+ }
+ else
+ {
+ int theme = mainActivity.getThemeIndex();
+ lockFollowButton(activity);
+ textViewFollowed.setText(R.string.user_detail_loading);
+ final Drawable red = Themes.getStyledDrawable(activity, theme, R.attr.button_round_red);
+ final Drawable blue = Themes.getStyledDrawable(activity, theme, R.attr.button_round_blue);
+ new ShowFriendshipTask(twitter, userId)
+ {
+ @Override
+ protected void onPostExecute(Relationship relationship)
+ {
+ if(relationship != null)
+ {
+ boolean isFollowing = relationship.isSourceFollowingTarget();
+ boolean isFollowed = relationship.isSourceFollowedByTarget();
+ setFollowButtonState(isFollowing, red, blue);
+ textViewFollowed.setText(isFollowed ? R.string.user_detail_followed : R.string.user_detail_not_followed);
+ }
+ }
+ }.execute();
+ }
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/UserMenuDialogFragment.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/UserMenuDialogFragment.java
new file mode 100644
index 00000000..92d226e4
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/dialog/UserMenuDialogFragment.java
@@ -0,0 +1,133 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.command.Command;
+import net.lacolaco.smileessence.command.CommandSearchOnTwitter;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter;
+import twitter4j.User;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UserMenuDialogFragment extends MenuDialogFragment
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private static final String KEY_USER_ID = "userID";
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public long getUserID()
+ {
+ return getArguments().getLong(KEY_USER_ID);
+ }
+
+ public void setUserID(long userID)
+ {
+ Bundle args = new Bundle();
+ args.putLong(KEY_USER_ID, userID);
+ setArguments(args);
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState)
+ {
+ final MainActivity activity = (MainActivity) getActivity();
+ final Account account = activity.getCurrentAccount();
+ View body = activity.getLayoutInflater().inflate(R.layout.dialog_menu_list, null);
+ ListView listView = (ListView) body.findViewById(R.id.listview_dialog_menu_list);
+ final CustomListAdapter<Command> adapter = new CustomListAdapter<>(activity, Command.class);
+ listView.setAdapter(adapter);
+ listView.setOnItemClickListener(onItemClickListener);
+
+ TwitterUtils.tryGetUser(account, getUserID(), new TwitterUtils.UserCallback()
+ {
+ @Override
+ public void success(User user)
+ {
+ List<Command> commands = getCommands(activity, user, account);
+ Command.filter(commands);
+ for(Command command : commands)
+ {
+ adapter.addToBottom(command);
+ }
+ adapter.update();
+ }
+
+ @Override
+ public void error()
+ {
+ dismiss();
+ }
+ });
+
+ return new AlertDialog.Builder(activity)
+ .setView(body)
+ .setCancelable(true)
+ .create();
+ }
+
+ @Override
+ protected void onItemClick(AdapterView<?> adapterView, int i)
+ {
+ super.onItemClick(adapterView, i);
+ dismiss();
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public boolean addBottomCommands(Activity activity, User user, ArrayList<Command> commands)
+ {
+ return commands.add(new CommandSearchOnTwitter(activity, user.getScreenName()));
+ }
+
+ public boolean addMainCommands(Activity activity, User user, Account account, ArrayList<Command> commands)
+ {
+ return commands.addAll(Command.getUserCommands(activity, user, account));
+ }
+
+ public List<Command> getCommands(Activity activity, User user, Account account)
+ {
+ ArrayList<Command> commands = new ArrayList<>();
+ addMainCommands(activity, user, account, commands);
+ addBottomCommands(activity, user, commands);
+ return commands;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/view/listener/ListItemClickListener.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/listener/ListItemClickListener.java
new file mode 100644
index 00000000..697e995c
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/view/listener/ListItemClickListener.java
@@ -0,0 +1,71 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.listener;
+
+import android.app.Activity;
+import android.graphics.drawable.ColorDrawable;
+import android.view.View;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.util.UIHandler;
+
+public class ListItemClickListener implements View.OnClickListener
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final Activity activity;
+ private final Runnable callback;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public ListItemClickListener(Activity activity, Runnable callback)
+ {
+ this.activity = activity;
+ this.callback = callback;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface OnClickListener ---------------------
+
+ @Override
+ public void onClick(final View v)
+ {
+ final int currentBgColor = ((ColorDrawable) v.getBackground()).getColor();
+ v.setBackgroundColor(activity.getResources().getColor(R.color.metro_blue));
+ v.invalidate();
+ new UIHandler()
+ {
+
+ @Override
+ public void run()
+ {
+ v.setBackgroundColor(currentBgColor);
+ callback.run();
+ }
+ }.post();
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/CheckBoxModel.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/CheckBoxModel.java
new file mode 100644
index 00000000..b43bcb9a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/CheckBoxModel.java
@@ -0,0 +1,87 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import net.lacolaco.smileessence.R;
+
+public class CheckBoxModel implements IViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String text;
+ private boolean checked;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public CheckBoxModel(String text, boolean isChecked)
+ {
+ this.text = text;
+ checked = isChecked;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public boolean isChecked()
+ {
+ return checked;
+ }
+
+ public void setChecked(boolean checked)
+ {
+ this.checked = checked;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface IViewModel ---------------------
+
+ @Override
+ public View getView(Activity activity, LayoutInflater inflater, View convertedView)
+ {
+ if(convertedView == null)
+ {
+ convertedView = inflater.inflate(R.layout.menu_item_checkbox, null);
+ }
+ CheckBox checkBox = (CheckBox) convertedView.findViewById(R.id.checkBox_menuItem);
+ checkBox.setText(this.text);
+ checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
+ {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
+ {
+ CheckBoxModel.this.checked = isChecked;
+ }
+ });
+ checkBox.setChecked(checked);
+ return convertedView;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EditableCheckBoxModel.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EditableCheckBoxModel.java
new file mode 100644
index 00000000..3694aee1
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EditableCheckBoxModel.java
@@ -0,0 +1,134 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import android.app.Activity;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import net.lacolaco.smileessence.R;
+
+public class EditableCheckBoxModel implements IViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private final String text;
+ private boolean freezing;
+ private String inputText;
+ private boolean checked;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public EditableCheckBoxModel(String text)
+ {
+ this.text = text;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public String getInputText()
+ {
+ return inputText;
+ }
+
+ public EditableCheckBoxModel setInputText(String inputText)
+ {
+ this.inputText = inputText;
+ return this;
+ }
+
+ public boolean isChecked()
+ {
+ return checked;
+ }
+
+ public EditableCheckBoxModel setChecked(boolean checked)
+ {
+ this.checked = checked;
+ return this;
+ }
+
+ public boolean isFreezing()
+ {
+ return freezing;
+ }
+
+ public EditableCheckBoxModel setFreezing(boolean freezing)
+ {
+ this.freezing = freezing;
+ return this;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface IViewModel ---------------------
+
+ @Override
+ public View getView(Activity activity, LayoutInflater inflater, View convertedView)
+ {
+ if(convertedView == null)
+ {
+ convertedView = inflater.inflate(R.layout.menu_item_editable_checkbox, null);
+ }
+ CheckBox checkBox = (CheckBox) convertedView.findViewById(R.id.checkBox_menuItem);
+ checkBox.setText(this.text);
+ checkBox.setChecked(checked);
+ checkBox.setEnabled(!isFreezing());
+ checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
+ {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
+ {
+ EditableCheckBoxModel.this.setChecked(isChecked);
+ }
+ });
+ EditText editText = (EditText) convertedView.findViewById(R.id.edittext_editable_checkbox);
+ editText.addTextChangedListener(new TextWatcher()
+ {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after)
+ {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count)
+ {
+ EditableCheckBoxModel.this.setInputText(s.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable s)
+ {
+ }
+ });
+ return convertedView;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EnumEvent.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EnumEvent.java
new file mode 100644
index 00000000..7a019492
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EnumEvent.java
@@ -0,0 +1,58 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import net.lacolaco.smileessence.R;
+
+public enum EnumEvent
+{
+
+ FAVORITED(R.string.format_event_favorited),
+ UNFAVORITED(R.string.format_event_unfavorited),
+ RETWEETED(R.string.format_event_retweeted),
+ MENTIONED(R.string.format_event_mentioned),
+ FOLLOWED(R.string.format_event_followed),
+ BLOCKED(R.string.format_event_blocked),
+ UNBLOCKED(R.string.format_event_unblocked),
+ RECEIVE_MESSAGE(R.string.format_event_message);
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private int textFormatResourceID;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ private EnumEvent(int textFormatResourceID)
+ {
+ this.textFormatResourceID = textFormatResourceID;
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public int getTextFormatResourceID()
+ {
+ return textFormatResourceID;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EventViewModel.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EventViewModel.java
new file mode 100644
index 00000000..1d59b1b1
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/EventViewModel.java
@@ -0,0 +1,201 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.android.volley.toolbox.NetworkImageView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.ImageCache;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.util.StringUtils;
+import net.lacolaco.smileessence.util.Themes;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment;
+import net.lacolaco.smileessence.view.listener.ListItemClickListener;
+import twitter4j.Status;
+import twitter4j.User;
+
+import java.util.Date;
+
+public class EventViewModel implements IViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private EnumEvent event;
+ private long sourceUserID;
+ private long targetStatusID;
+ private String sourceScreenName;
+ private String sourceName;
+ private String iconURL;
+ private String targetText;
+ private Date createdAt;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public EventViewModel(EnumEvent event, User source)
+ {
+ this(event, source, null);
+ }
+
+ public EventViewModel(EnumEvent event, User source, Status status)
+ {
+ this.event = event;
+ this.createdAt = new Date();
+ this.sourceUserID = source.getId();
+ this.sourceScreenName = source.getScreenName();
+ this.sourceName = source.getName();
+ this.iconURL = source.getProfileImageURL();
+
+ if(status != null)
+ {
+ if(event == EnumEvent.RETWEETED)
+ {
+ this.targetStatusID = status.getRetweetedStatus().getId();
+ this.targetText = status.getRetweetedStatus().getText();
+ }
+ else
+ {
+ this.targetStatusID = status.getId();
+ this.targetText = status.getText();
+ }
+ }
+ else
+ {
+ this.targetStatusID = -1L;
+ this.targetText = "";
+ }
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public Date getCreatedAt()
+ {
+ return createdAt;
+ }
+
+ public EnumEvent getEvent()
+ {
+ return event;
+ }
+
+ public String getIconURL()
+ {
+ return iconURL;
+ }
+
+ public String getSourceName()
+ {
+ return sourceName;
+ }
+
+ public String getSourceScreenName()
+ {
+ return sourceScreenName;
+ }
+
+ public long getSourceUserID()
+ {
+ return sourceUserID;
+ }
+
+ public long getTargetStatusID()
+ {
+ return targetStatusID;
+ }
+
+ public String getTargetText()
+ {
+ return targetText;
+ }
+
+ public boolean isStatusEvent()
+ {
+ return targetStatusID != -1L;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface IViewModel ---------------------
+
+ @Override
+ public View getView(final Activity activity, LayoutInflater inflater, View convertedView)
+ {
+ if(convertedView == null)
+ {
+ convertedView = inflater.inflate(R.layout.list_item_status, null);
+ }
+ UserPreferenceHelper preferenceHelper = new UserPreferenceHelper(activity);
+ int textSize = preferenceHelper.getValue(R.string.key_setting_text_size, 10);
+ int nameStyle = preferenceHelper.getValue(R.string.key_setting_namestyle, 0);
+ int theme = ((MainActivity) activity).getThemeIndex();
+ NetworkImageView icon = (NetworkImageView) convertedView.findViewById(R.id.imageview_status_icon);
+ ImageCache.getInstance().setImageToView(getIconURL(), icon);
+ TextView header = (TextView) convertedView.findViewById(R.id.textview_status_header);
+ header.setTextSize(textSize);
+ int colorHeader = Themes.getStyledColor(activity, theme, R.attr.color_status_text_mine, 0);
+ header.setTextColor(colorHeader);
+ header.setText(getFormattedString(activity));
+ TextView content = (TextView) convertedView.findViewById(R.id.textview_status_text);
+ content.setTextSize(textSize);
+ int colorNormal = Themes.getStyledColor(activity, theme, R.attr.color_status_text_normal, 0);
+ content.setTextColor(colorNormal);
+ content.setText(getTargetText());
+ TextView footer = (TextView) convertedView.findViewById(R.id.textview_status_footer);
+ footer.setTextSize(textSize - 2);
+ int colorFooter = Themes.getStyledColor(activity, theme, R.attr.color_status_text_footer, 0);
+ footer.setTextColor(colorFooter);
+ footer.setText(StringUtils.dateToString(getCreatedAt()));
+ ImageView favorited = (ImageView) convertedView.findViewById(R.id.imageview_status_favorited);
+ favorited.setVisibility(View.GONE);
+ int colorBgNormal = Themes.getStyledColor(activity, theme, R.attr.color_status_bg_normal, 0);
+ convertedView.setBackgroundColor(colorBgNormal);
+ convertedView.setOnClickListener(new ListItemClickListener(activity, new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ UserDetailDialogFragment fragment = new UserDetailDialogFragment();
+ fragment.setUserID(getSourceUserID());
+ DialogHelper.showDialog(activity, fragment);
+ }
+ }));
+ return convertedView;
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public String getFormattedString(Context context)
+ {
+ return context.getString(event.getTextFormatResourceID(), sourceScreenName);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/IViewModel.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/IViewModel.java
new file mode 100644
index 00000000..f4dee60d
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/IViewModel.java
@@ -0,0 +1,37 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+
+public interface IViewModel
+{
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ View getView(Activity activity, LayoutInflater inflater, View convertedView);
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/MessageViewModel.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/MessageViewModel.java
new file mode 100644
index 00000000..6210ee3e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/MessageViewModel.java
@@ -0,0 +1,215 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import android.app.Activity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.android.volley.toolbox.NetworkImageView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.ImageCache;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.util.NameStyles;
+import net.lacolaco.smileessence.util.StringUtils;
+import net.lacolaco.smileessence.util.Themes;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.MessageDetailDialogFragment;
+import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment;
+import net.lacolaco.smileessence.view.listener.ListItemClickListener;
+import twitter4j.DirectMessage;
+
+import java.util.Date;
+
+public class MessageViewModel implements IViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String DETAIL_DIALOG = "messageDetail";
+ private final long id;
+ private final long senderID;
+ private final String senderScreenName;
+ private final String senderName;
+ private final String senderIconURL;
+ private final long recipientId;
+ private final String recipientScreenName;
+ private final String text;
+ private final Date createdAt;
+ private final boolean myMessage;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public MessageViewModel(DirectMessage directMessage, Account account)
+ {
+ id = directMessage.getId();
+ UserCache.getInstance().put(directMessage.getSender());
+ senderID = directMessage.getSenderId();
+ senderScreenName = directMessage.getSenderScreenName();
+ senderName = directMessage.getSender().getName();
+ senderIconURL = directMessage.getSender().getProfileImageURL();
+ recipientId = directMessage.getRecipientId();
+ recipientScreenName = directMessage.getRecipientScreenName();
+ text = directMessage.getText();
+ createdAt = directMessage.getCreatedAt();
+ myMessage = isMyMessage(account);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public Date getCreatedAt()
+ {
+ return createdAt;
+ }
+
+ private String getFooterText()
+ {
+ String s = StringUtils.dateToString(getCreatedAt());
+ if(isMyMessage())
+ {
+ s = String.format("%s to @%s", s, recipientScreenName);
+ }
+ return s;
+ }
+
+ public long getID()
+ {
+ return id;
+ }
+
+ public long getRecipientId()
+ {
+ return recipientId;
+ }
+
+ public String getRecipientScreenName()
+ {
+ return recipientScreenName;
+ }
+
+ public String getSenderIconURL()
+ {
+ return senderIconURL;
+ }
+
+ public long getSenderID()
+ {
+ return senderID;
+ }
+
+ public String getSenderName()
+ {
+ return senderName;
+ }
+
+ public String getSenderScreenName()
+ {
+ return senderScreenName;
+ }
+
+ public String getText()
+ {
+ return text;
+ }
+
+ public boolean isMyMessage()
+ {
+ return myMessage;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface IViewModel ---------------------
+
+ @Override
+ public View getView(final Activity activity, LayoutInflater inflater, View convertedView)
+ {
+ if(convertedView == null)
+ {
+ convertedView = inflater.inflate(R.layout.list_item_status, null);
+ }
+ UserPreferenceHelper preferenceHelper = new UserPreferenceHelper(activity);
+ int textSize = preferenceHelper.getValue(R.string.key_setting_text_size, 10);
+ int nameStyle = preferenceHelper.getValue(R.string.key_setting_namestyle, 0);
+ int theme = ((MainActivity) activity).getThemeIndex();
+ NetworkImageView icon = (NetworkImageView) convertedView.findViewById(R.id.imageview_status_icon);
+ ImageCache.getInstance().setImageToView(getSenderIconURL(), icon);
+ icon.setOnClickListener(new View.OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ UserDetailDialogFragment dialogFragment = new UserDetailDialogFragment();
+ dialogFragment.setUserID(senderID);
+ DialogHelper.showDialog(activity, dialogFragment);
+ }
+ });
+ TextView header = (TextView) convertedView.findViewById(R.id.textview_status_header);
+ header.setTextSize(textSize);
+ int colorHeader = Themes.getStyledColor(activity, theme, R.attr.color_message_text_header, 0);
+ header.setTextColor(colorHeader);
+ header.setText(getNameString(nameStyle));
+ TextView content = (TextView) convertedView.findViewById(R.id.textview_status_text);
+ content.setTextSize(textSize);
+ int colorNormal = Themes.getStyledColor(activity, theme, R.attr.color_status_text_normal, 0);
+ content.setTextColor(colorNormal);
+ content.setText(getText());
+ TextView footer = (TextView) convertedView.findViewById(R.id.textview_status_footer);
+ footer.setTextSize(textSize - 2);
+ int colorFooter = Themes.getStyledColor(activity, theme, R.attr.color_status_text_footer, 0);
+ footer.setTextColor(colorFooter);
+ footer.setText(getFooterText());
+ ImageView favorited = (ImageView) convertedView.findViewById(R.id.imageview_status_favorited);
+ favorited.setVisibility(View.GONE);
+ int colorBgMessage = Themes.getStyledColor(activity, theme, R.attr.color_message_bg_normal, 0);
+ convertedView.setBackgroundColor(colorBgMessage);
+ convertedView.setOnClickListener(new ListItemClickListener(activity, new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ MessageDetailDialogFragment dialogFragment = new MessageDetailDialogFragment();
+ dialogFragment.setMessageID(getID());
+ DialogHelper.showDialog(activity, dialogFragment);
+ }
+ }));
+ return convertedView;
+ }
+
+ private String getNameString(int nameStyle)
+ {
+ return NameStyles.getNameString(nameStyle, getSenderScreenName(), getSenderName());
+ }
+
+ private boolean isMyMessage(Account account)
+ {
+ return senderID == account.userID;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/StatusViewModel.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/StatusViewModel.java
new file mode 100644
index 00000000..3a11737a
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/StatusViewModel.java
@@ -0,0 +1,497 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import android.app.Activity;
+import android.net.Uri;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.android.volley.toolbox.NetworkImageView;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.MainActivity;
+import net.lacolaco.smileessence.data.FavoriteCache;
+import net.lacolaco.smileessence.data.ImageCache;
+import net.lacolaco.smileessence.data.UserCache;
+import net.lacolaco.smileessence.entity.Account;
+import net.lacolaco.smileessence.preference.UserPreferenceHelper;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.util.Morse;
+import net.lacolaco.smileessence.util.NameStyles;
+import net.lacolaco.smileessence.util.StringUtils;
+import net.lacolaco.smileessence.util.Themes;
+import net.lacolaco.smileessence.view.dialog.DialogHelper;
+import net.lacolaco.smileessence.view.dialog.StatusDetailDialogFragment;
+import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment;
+import net.lacolaco.smileessence.view.listener.ListItemClickListener;
+import twitter4j.*;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class StatusViewModel implements IViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ public static final String STATUS_DIALOG = "statusDialog";
+ private long id;
+ private long userID;
+ private String screenName;
+ private String name;
+ private String iconURL;
+ private String text;
+ private Date createdAt;
+ private String source;
+ private boolean isProtected;
+ private StatusViewModel retweetedStatus;
+ private UserMentionEntity[] mentions;
+ private HashtagEntity[] hashtags;
+ private MediaEntity[] media;
+ private URLEntity[] urls;
+ private SymbolEntity[] symbols;
+ private boolean isMyStatus;
+ private boolean isMention;
+ private boolean isRetweetOfMe;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public StatusViewModel(Status status, Account account)
+ {
+ if(status.isRetweet())
+ {
+ retweetedStatus = new StatusViewModel(status.getRetweetedStatus(), account);
+ }
+ id = status.getId();
+ text = TwitterUtils.replaceURLEntities(status.getText(), status.getURLEntities(), false);
+ createdAt = status.getCreatedAt();
+ source = status.getSource();
+ mentions = status.getUserMentionEntities();
+ hashtags = status.getHashtagEntities();
+ media = status.getMediaEntities();
+ urls = status.getURLEntities();
+ symbols = status.getSymbolEntities();
+ User user = status.getUser();
+ UserCache.getInstance().put(user);
+ userID = user.getId();
+ screenName = user.getScreenName();
+ name = user.getName();
+ iconURL = user.getProfileImageURLHttps();
+ isProtected = user.isProtected();
+ setMention(isMention(account.screenName));
+ setMyStatus(isMyStatus(account.userID));
+ setRetweetOfMe(isRetweetOfMe(account.userID));
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public Date getCreatedAt()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.createdAt;
+ }
+ return createdAt;
+ }
+
+ private List<Long> getEmbeddedStatusIDs()
+ {
+ ArrayList<Long> list = new ArrayList<>();
+ for(URLEntity url : urls)
+ {
+ Uri uri = Uri.parse(url.getExpandedURL());
+ if(uri.getHost().equals("twitter.com"))
+ {
+ String[] arr = uri.toString().split("/");
+ if(arr[arr.length - 2].equals("status"))
+ {
+ list.add(Long.parseLong(arr[arr.length - 1].split("\\?")[0]));
+ }
+ }
+ }
+ return list;
+ }
+
+ private String getFooterText()
+ {
+ StringBuilder builder = new StringBuilder();
+ if(isRetweet())
+ {
+ builder.append("(RT: ").append(this.screenName).append(") ");
+ }
+ builder.append(StringUtils.dateToString(getCreatedAt()));
+ builder.append(" via ");
+ builder.append(Html.fromHtml(getSource()));
+ return builder.toString();
+ }
+
+ public HashtagEntity[] getHashtags()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.hashtags;
+ }
+ return hashtags;
+ }
+
+ public String getIconURL()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.iconURL;
+ }
+ return iconURL;
+ }
+
+ public long getID()
+ {
+ return id;
+ }
+
+ public MediaEntity[] getMedia()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.media;
+ }
+ return media;
+ }
+
+ public UserMentionEntity[] getMentions()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.mentions;
+ }
+ return mentions;
+ }
+
+ public String getName()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.name;
+ }
+ return name;
+ }
+
+ public StatusViewModel getOriginal()
+ {
+ return isRetweet() ? retweetedStatus : this;
+ }
+
+ public long getOriginalUserID()
+ {
+ return isRetweet() ? getRetweetedStatus().getUserID() : getUserID();
+ }
+
+ public StatusViewModel getRetweetedStatus()
+ {
+ return retweetedStatus;
+ }
+
+ public String getScreenName()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.screenName;
+ }
+ return screenName;
+ }
+
+ public String getSource()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.source;
+ }
+ return source;
+ }
+
+ public SymbolEntity[] getSymbols()
+ {
+ return symbols;
+ }
+
+ public String getText()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.text;
+ }
+ return text;
+ }
+
+ public URLEntity[] getURLs()
+ {
+ return urls;
+ }
+
+ public long getUserID()
+ {
+ return userID;
+ }
+
+ public boolean isFavorited()
+ {
+ if(isRetweet())
+ {
+ return FavoriteCache.getInstance().get(retweetedStatus.id);
+ }
+ return FavoriteCache.getInstance().get(id);
+ }
+
+ public boolean isMention()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.isMention;
+ }
+ return isMention;
+ }
+
+ public void setMention(boolean mention)
+ {
+ isMention = mention;
+ }
+
+ public boolean isMyStatus()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.isMyStatus;
+ }
+ return isMyStatus;
+ }
+
+ public void setMyStatus(boolean myStatus)
+ {
+ isMyStatus = myStatus;
+ }
+
+ public boolean isProtected()
+ {
+ if(isRetweet())
+ {
+ return retweetedStatus.isProtected;
+ }
+ return isProtected;
+ }
+
+ public boolean isRetweet()
+ {
+ return retweetedStatus != null;
+ }
+
+ public boolean isRetweetOfMe()
+ {
+ return isRetweetOfMe;
+ }
+
+ public void setRetweetOfMe(boolean retweet)
+ {
+ this.isRetweetOfMe = retweet;
+ }
+
+ // ------------------------ INTERFACE METHODS ------------------------
+
+
+ // --------------------- Interface IViewModel ---------------------
+
+ @Override
+ public View getView(final Activity activity, final LayoutInflater inflater, View convertedView)
+ {
+ boolean extendStatusURL = new UserPreferenceHelper(activity).getValue(R.string.key_setting_extend_status_url, true);
+ return getView(activity, inflater, convertedView, extendStatusURL);
+ }
+
+ // -------------------------- OTHER METHODS --------------------------
+
+ public View getView(final Activity activity, final LayoutInflater inflater, View convertedView, boolean extendStatusURL)
+ {
+ if(convertedView == null)
+ {
+ convertedView = inflater.inflate(R.layout.list_item_status, null);
+ }
+ UserPreferenceHelper preferenceHelper = new UserPreferenceHelper(activity);
+ int textSize = preferenceHelper.getValue(R.string.key_setting_text_size, 10);
+ int nameStyle = preferenceHelper.getValue(R.string.key_setting_namestyle, 0);
+ int theme = ((MainActivity) activity).getThemeIndex();
+ NetworkImageView icon = (NetworkImageView) convertedView.findViewById(R.id.imageview_status_icon);
+ ImageCache.getInstance().setImageToView(getIconURL(), icon);
+ icon.setOnClickListener(new View.OnClickListener()
+ {
+ @Override
+ public void onClick(View v)
+ {
+ onIconClick(activity);
+ }
+ });
+ TextView header = (TextView) convertedView.findViewById(R.id.textview_status_header);
+ header.setTextSize(textSize);
+ int colorHeader = Themes.getStyledColor(activity, theme, R.attr.color_status_text_header, 0);
+ int colorMineHeader = Themes.getStyledColor(activity, theme, R.attr.color_status_text_mine, 0);
+ header.setTextColor(isMyStatus() ? colorMineHeader : colorHeader);
+ header.setText(NameStyles.getNameString(nameStyle, getScreenName(), getName()));
+ TextView content = (TextView) convertedView.findViewById(R.id.textview_status_text);
+ content.setTextSize(textSize);
+ int colorNormal = Themes.getStyledColor(activity, theme, R.attr.color_status_text_normal, 0);
+ content.setTextColor(colorNormal);
+ String rawText = getText();
+ if(isReadMorseEnabled((MainActivity) activity) && Morse.isMorse(rawText))
+ {
+ content.setText(String.format("%s\n(%s)", rawText, Morse.morseToJa(rawText)));
+ }
+ else
+ {
+ content.setText(rawText);
+ }
+ TextView footer = (TextView) convertedView.findViewById(R.id.textview_status_footer);
+ footer.setTextSize(textSize - 2);
+ int colorFooter = Themes.getStyledColor(activity, theme, R.attr.color_status_text_footer, 0);
+ footer.setTextColor(colorFooter);
+ footer.setText(getFooterText());
+ ImageView favorited = (ImageView) convertedView.findViewById(R.id.imageview_status_favorited);
+ favorited.setVisibility(isFavorited() ? View.VISIBLE : View.GONE);
+ if(isRetweet())
+ {
+ int colorBgRetweet = Themes.getStyledColor(activity, theme, R.attr.color_status_bg_retweet, 0);
+ convertedView.setBackgroundColor(colorBgRetweet);
+ }
+ else if(isMention())
+ {
+ int colorBgMention = Themes.getStyledColor(activity, theme, R.attr.color_status_bg_mention, 0);
+ convertedView.setBackgroundColor(colorBgMention);
+ }
+ else
+ {
+ int colorBgNormal = Themes.getStyledColor(activity, theme, R.attr.color_status_bg_normal, 0);
+ convertedView.setBackgroundColor(colorBgNormal);
+ }
+ convertedView.setOnClickListener(new ListItemClickListener(activity, new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ onClick(activity);
+ }
+ }));
+ final ViewGroup embeddedStatus = (ViewGroup) convertedView.findViewById(R.id.view_status_embedded_status);
+ embeddedStatus.removeAllViews();
+ if(extendStatusURL)
+ {
+ if(containsStatusURL())
+ {
+ embeddedStatus.setVisibility(View.VISIBLE);
+ final Account account = ((MainActivity) activity).getCurrentAccount();
+ List<Long> embeddedStatusIDs = getEmbeddedStatusIDs();
+ for(int i = 0; i < embeddedStatusIDs.size(); i++)
+ {
+ long id = embeddedStatusIDs.get(i);
+ final int index = i;
+ final View finalConvertedView = convertedView;
+ TwitterUtils.tryGetStatus(account, id, new TwitterUtils.StatusCallback()
+ {
+ @Override
+ public void success(Status status)
+ {
+ StatusViewModel viewModel = new StatusViewModel(status, account);
+ View embeddedHolder = viewModel.getView(activity, inflater, null, false);
+ embeddedStatus.addView(embeddedHolder);
+ finalConvertedView.invalidate();
+ }
+
+ @Override
+ public void error()
+ {
+
+ }
+ });
+ }
+
+ }
+ }
+ else
+ {
+ embeddedStatus.setVisibility(View.GONE);
+ }
+ return convertedView;
+ }
+
+ public boolean isMention(String screenName)
+ {
+ if(mentions == null)
+ {
+ return false;
+ }
+ for(UserMentionEntity mention : mentions)
+ {
+ if(mention.getScreenName().equals(screenName))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isMyStatus(long userID)
+ {
+ return this.userID == userID;
+ }
+
+ public boolean isRetweetOfMe(long userID)
+ {
+ return retweetedStatus != null && retweetedStatus.getUserID() == userID;
+ }
+
+ private boolean containsStatusURL()
+ {
+ return getEmbeddedStatusIDs().size() > 0;
+ }
+
+ private boolean isReadMorseEnabled(MainActivity activity)
+ {
+ return activity.getUserPreferenceHelper().getValue(R.string.key_setting_read_morse, true);
+ }
+
+ private void onClick(Activity activity)
+ {
+ StatusDetailDialogFragment fragment = new StatusDetailDialogFragment();
+ fragment.setStatusID(getID());
+ DialogHelper.showDialog(activity, fragment, STATUS_DIALOG);
+ }
+
+ private void onIconClick(Activity activity)
+ {
+ DialogHelper.close(activity, STATUS_DIALOG);
+ UserDetailDialogFragment dialogFragment = new UserDetailDialogFragment();
+ dialogFragment.setUserID(isRetweet() ? getRetweetedStatus().userID : userID);
+ DialogHelper.showDialog(activity, dialogFragment);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/UserListListAdapter.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/UserListListAdapter.java
new file mode 100644
index 00000000..588829ec
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/UserListListAdapter.java
@@ -0,0 +1,69 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import android.app.Activity;
+import net.lacolaco.smileessence.view.adapter.StatusListAdapter;
+
+public class UserListListAdapter extends StatusListAdapter
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private String listFullName;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserListListAdapter(Activity activity)
+ {
+ super(activity);
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public String getListFullName()
+ {
+ return listFullName;
+ }
+
+ public void setListFullName(String listFullName)
+ {
+ this.listFullName = listFullName;
+ }
+
+ // ------------------------ OVERRIDE METHODS ------------------------
+
+ @Override
+ public void addToBottom(StatusViewModel... items)
+ {
+ super.addToBottom(items);
+ }
+
+ @Override
+ public void addToTop(StatusViewModel... items)
+ {
+ super.addToTop(items);
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/UserViewModel.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/UserViewModel.java
new file mode 100644
index 00000000..99757e5e
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/UserViewModel.java
@@ -0,0 +1,140 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel;
+
+import twitter4j.User;
+
+public class UserViewModel
+{
+
+ // ------------------------------ FIELDS ------------------------------
+
+ private long id;
+ private String screenName;
+ private String name;
+ private String description;
+ private String location;
+ private String url;
+ private String iconURL;
+ private String bannerURL;
+ private int statusesCount;
+ private int friendsCount;
+ private int followersCount;
+ private int favoritesCount;
+ private boolean isProtected;
+ private boolean isVerified;
+
+ // --------------------------- CONSTRUCTORS ---------------------------
+
+ public UserViewModel(User user)
+ {
+ id = user.getId();
+ screenName = user.getScreenName();
+ name = user.getName();
+ description = user.getDescription();
+ location = user.getLocation();
+ url = user.getURL();
+ iconURL = user.getBiggerProfileImageURL();
+ bannerURL = user.getProfileBannerURL();
+ statusesCount = user.getStatusesCount();
+ friendsCount = user.getFriendsCount();
+ followersCount = user.getFollowersCount();
+ favoritesCount = user.getFavouritesCount();
+ isProtected = user.isProtected();
+ isVerified = user.isVerified();
+ }
+
+ // --------------------- GETTER / SETTER METHODS ---------------------
+
+ public String getBannerURL()
+ {
+ return bannerURL;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public int getFavoritesCount()
+ {
+ return favoritesCount;
+ }
+
+ public int getFollowersCount()
+ {
+ return followersCount;
+ }
+
+ public int getFriendsCount()
+ {
+ return friendsCount;
+ }
+
+ public String getIconURL()
+ {
+ return iconURL;
+ }
+
+ public long getID()
+ {
+ return id;
+ }
+
+ public String getLocation()
+ {
+ return location;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getScreenName()
+ {
+ return screenName;
+ }
+
+ public int getStatusesCount()
+ {
+ return statusesCount;
+ }
+
+ public String getURL()
+ {
+ return url;
+ }
+
+ public boolean isProtected()
+ {
+ return isProtected;
+ }
+
+ public boolean isVerified()
+ {
+ return isVerified;
+ }
+}
diff --git a/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/menu/MainActivityMenuHelper.java b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/menu/MainActivityMenuHelper.java
new file mode 100644
index 00000000..63d2bc43
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/smileessence/viewmodel/menu/MainActivityMenuHelper.java
@@ -0,0 +1,157 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.viewmodel.menu;
+
+import android.content.Intent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.SubMenu;
+import net.lacolaco.smileessence.R;
+import net.lacolaco.smileessence.activity.*;
+import net.lacolaco.smileessence.command.CommandOpenURL;
+import net.lacolaco.smileessence.twitter.util.TwitterUtils;
+import net.lacolaco.smileessence.view.adapter.PostState;
+
+public class MainActivityMenuHelper
+{
+
+ // -------------------------- STATIC METHODS --------------------------
+
+ public static void addItemsToMenu(MainActivity activity, Menu menu)
+ {
+ //Post button
+ MenuItem postButton = menu.add(Menu.NONE, R.id.actionbar_post, Menu.NONE, activity.getString(R.string.actionbar_post));
+ postButton.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ postButton.setIcon(R.drawable.icon_edit);
+ //Search button
+ // MenuItem searchButton = menu.add(Menu.NONE, R.id.actionbar_search, Menu.NONE, activity.getString(R.string.actionbar_search));
+ // searchButton.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+ // searchButton.setIcon(R.drawable.icon_search_white);
+ //Settings
+ SubMenu settings = menu.addSubMenu(Menu.NONE, R.id.actionbar_settings, Menu.NONE, activity.getString(R.string.actionbar_settings));
+ settings.setIcon(R.drawable.icon_settings);
+ settings.getItem().setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ settings.add(Menu.NONE, R.id.actionbar_setting, Menu.NONE, activity.getString(R.string.actionbar_setting));
+ settings.add(Menu.NONE, R.id.actionbar_edit_templates, Menu.NONE, activity.getString(R.string.actionbar_edit_templates));
+ settings.add(Menu.NONE, R.id.actionbar_edit_extraction, Menu.NONE, activity.getString(R.string.actionbar_edit_extraction));
+ settings.add(Menu.NONE, R.id.actionbar_edit_commands, Menu.NONE, activity.getString(R.string.actionbar_edit_commands));
+ settings.add(Menu.NONE, R.id.actionbar_edit_tabs, Menu.NONE, activity.getString(R.string.actionbar_edit_tabs));
+ //External services
+ SubMenu services = menu.addSubMenu(Menu.NONE, R.id.actionbar_services, Menu.NONE, activity.getString(R.string.actionbar_services));
+ services.setIcon(R.drawable.icon_website);
+ services.getItem().setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ services.add(Menu.NONE, R.id.actionbar_favstar, Menu.NONE, activity.getString(R.string.actionbar_favstar));
+ services.add(Menu.NONE, R.id.actionbar_aclog, Menu.NONE, activity.getString(R.string.actionbar_aclog));
+ services.add(Menu.NONE, R.id.actionbar_twilog, Menu.NONE, activity.getString(R.string.actionbar_twilog));
+ //Report to author
+ MenuItem report = menu.add(Menu.NONE, R.id.actionbar_report, Menu.NONE, activity.getString(R.string.actionbar_report));
+ report.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ report.setIcon(R.drawable.icon_email);
+ }
+
+ public static boolean onItemSelected(MainActivity activity, MenuItem item)
+ {
+ switch(item.getItemId())
+ {
+ case R.id.actionbar_post:
+ {
+ openPostPage(activity);
+ return true;
+ }
+ case R.id.actionbar_search:
+ {
+ openSearchPage(activity);
+ return true;
+ }
+ case R.id.actionbar_setting:
+ {
+ Intent intent = new Intent(activity, SettingActivity.class);
+ activity.startActivity(intent);
+ return true;
+ }
+ case R.id.actionbar_edit_templates:
+ {
+ Intent intent = new Intent(activity, EditTemplateActivity.class);
+ activity.startActivity(intent);
+ return true;
+ }
+ case R.id.actionbar_edit_extraction:
+ {
+ Intent intent = new Intent(activity, EditExtractionActivity.class);
+ activity.startActivity(intent);
+ return true;
+ }
+ case R.id.actionbar_edit_commands:
+ {
+ Intent intent = new Intent(activity, EditCommandActivity.class);
+ activity.startActivity(intent);
+ return true;
+ }
+ case R.id.actionbar_edit_tabs:
+ {
+ Intent intent = new Intent(activity, EditTabActivity.class);
+ activity.startActivity(intent);
+ return true;
+ }
+ case R.id.actionbar_favstar:
+ {
+ new CommandOpenURL(activity, TwitterUtils.getFavstarRecentURL(activity.getCurrentAccount().screenName)).execute();
+ return true;
+ }
+ case R.id.actionbar_aclog:
+ {
+ new CommandOpenURL(activity, TwitterUtils.getAclogTimelineURL(activity.getCurrentAccount().screenName)).execute();
+ return true;
+ }
+ case R.id.actionbar_twilog:
+ {
+ new CommandOpenURL(activity, TwitterUtils.getTwilogURL(activity.getCurrentAccount().screenName)).execute();
+ return true;
+ }
+ case R.id.actionbar_report:
+ {
+ PostState.getState().beginTransaction()
+ .appendText(activity.getString(R.string.text_message_to_author, activity.getVersion()))
+ .commitWithOpen(activity);
+ return true;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+ }
+
+ private static void openPostPage(MainActivity activity)
+ {
+ activity.openPostPage();
+ }
+
+ private static void openSearchPage(MainActivity activity)
+ {
+ activity.openSearchPage();
+ }
+
+}