1package eu.siacs.conversations.ui;
2
3import android.app.PendingIntent;
4import android.content.Intent;
5import android.content.pm.PackageManager;
6import android.graphics.Bitmap;
7import android.net.Uri;
8import android.os.Bundle;
9import android.view.Menu;
10import android.view.MenuItem;
11import android.view.View;
12import android.view.View.OnClickListener;
13import android.view.View.OnLongClickListener;
14import android.widget.Button;
15import android.widget.ImageView;
16import android.widget.TextView;
17import android.widget.Toast;
18
19import com.soundcloud.android.crop.Crop;
20
21import java.io.File;
22
23import eu.siacs.conversations.Config;
24import eu.siacs.conversations.R;
25import eu.siacs.conversations.entities.Account;
26import eu.siacs.conversations.utils.FileUtils;
27import eu.siacs.conversations.utils.PhoneHelper;
28import eu.siacs.conversations.xmpp.pep.Avatar;
29
30public class PublishProfilePictureActivity extends XmppActivity {
31
32 private static final int REQUEST_CHOOSE_FILE_AND_CROP = 0xac23;
33 private static final int REQUEST_CHOOSE_FILE = 0xac24;
34 private ImageView avatar;
35 private TextView accountTextView;
36 private TextView hintOrWarning;
37 private TextView secondaryHint;
38 private Button cancelButton;
39 private Button publishButton;
40 private Uri avatarUri;
41 private Uri defaultUri;
42 private Account account;
43 private boolean support = false;
44 private OnLongClickListener backToDefaultListener = new OnLongClickListener() {
45
46 @Override
47 public boolean onLongClick(View v) {
48 avatarUri = defaultUri;
49 loadImageIntoPreview(defaultUri);
50 return true;
51 }
52 };
53 private boolean mInitialAccountSetup;
54 private UiCallback<Avatar> avatarPublication = new UiCallback<Avatar>() {
55
56 @Override
57 public void success(Avatar object) {
58 runOnUiThread(new Runnable() {
59
60 @Override
61 public void run() {
62 if (mInitialAccountSetup) {
63 Intent intent = new Intent(getApplicationContext(),
64 StartConversationActivity.class);
65 intent.putExtra("init", true);
66 startActivity(intent);
67 }
68 Toast.makeText(PublishProfilePictureActivity.this,
69 R.string.avatar_has_been_published,
70 Toast.LENGTH_SHORT).show();
71 finish();
72 }
73 });
74 }
75
76 @Override
77 public void error(final int errorCode, Avatar object) {
78 runOnUiThread(new Runnable() {
79
80 @Override
81 public void run() {
82 hintOrWarning.setText(errorCode);
83 hintOrWarning.setTextColor(getWarningTextColor());
84 publishButton.setText(R.string.publish);
85 enablePublishButton();
86 }
87 });
88
89 }
90
91 @Override
92 public void userInputRequried(PendingIntent pi, Avatar object) {
93 }
94 };
95
96 @Override
97 public void onCreate(Bundle savedInstanceState) {
98 super.onCreate(savedInstanceState);
99 setContentView(R.layout.activity_publish_profile_picture);
100 this.avatar = (ImageView) findViewById(R.id.account_image);
101 this.cancelButton = (Button) findViewById(R.id.cancel_button);
102 this.publishButton = (Button) findViewById(R.id.publish_button);
103 this.accountTextView = (TextView) findViewById(R.id.account);
104 this.hintOrWarning = (TextView) findViewById(R.id.hint_or_warning);
105 this.secondaryHint = (TextView) findViewById(R.id.secondary_hint);
106 this.publishButton.setOnClickListener(new OnClickListener() {
107
108 @Override
109 public void onClick(View v) {
110 if (avatarUri != null) {
111 publishButton.setText(R.string.publishing);
112 disablePublishButton();
113 xmppConnectionService.publishAvatar(account, avatarUri,
114 avatarPublication);
115 }
116 }
117 });
118 this.cancelButton.setOnClickListener(new OnClickListener() {
119
120 @Override
121 public void onClick(View v) {
122 if (mInitialAccountSetup) {
123 Intent intent = new Intent(getApplicationContext(),
124 StartConversationActivity.class);
125 if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) {
126 intent.putExtra("init", true);
127 }
128 startActivity(intent);
129 }
130 finish();
131 }
132 });
133 this.avatar.setOnClickListener(new OnClickListener() {
134
135 @Override
136 public void onClick(View v) {
137 if (hasStoragePermission(REQUEST_CHOOSE_FILE)) {
138 chooseAvatar(false);
139 }
140
141 }
142 });
143 this.defaultUri = PhoneHelper.getSefliUri(getApplicationContext());
144 }
145
146 private void chooseAvatar(boolean crop) {
147 Intent attachFileIntent = new Intent();
148 attachFileIntent.setType("image/*");
149 attachFileIntent.setAction(Intent.ACTION_GET_CONTENT);
150 Intent chooser = Intent.createChooser(attachFileIntent, getString(R.string.attach_file));
151 startActivityForResult(chooser, crop ? REQUEST_CHOOSE_FILE_AND_CROP : REQUEST_CHOOSE_FILE);
152 }
153
154 @Override
155 public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
156 if (grantResults.length > 0)
157 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
158 if (requestCode == REQUEST_CHOOSE_FILE_AND_CROP) {
159 chooseAvatar(true);
160 } else if (requestCode == REQUEST_CHOOSE_FILE) {
161 chooseAvatar(false);
162 }
163 } else {
164 Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
165 }
166 }
167
168 @Override
169 public boolean onCreateOptionsMenu(Menu menu) {
170 getMenuInflater().inflate(R.menu.publish_avatar, menu);
171 return super.onCreateOptionsMenu(menu);
172 }
173
174 @Override
175 public boolean onOptionsItemSelected(final MenuItem item) {
176 if (item.getItemId() == R.id.action_crop_image) {
177 if (hasStoragePermission(REQUEST_CHOOSE_FILE_AND_CROP)) {
178 chooseAvatar(true);
179 }
180 return true;
181 } else {
182 return super.onOptionsItemSelected(item);
183 }
184 }
185
186 @Override
187 protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
188 super.onActivityResult(requestCode, resultCode, data);
189 if (resultCode == RESULT_OK) {
190 switch (requestCode) {
191 case REQUEST_CHOOSE_FILE_AND_CROP:
192 Uri source = data.getData();
193 String original = FileUtils.getPath(this, source);
194 if (original != null) {
195 source = Uri.parse("file://"+original);
196 }
197 Uri destination = Uri.fromFile(new File(getCacheDir(), "croppedAvatar"));
198 final int size = getPixel(192);
199 Crop.of(source, destination).asSquare().withMaxSize(size, size).start(this);
200 break;
201 case REQUEST_CHOOSE_FILE:
202 this.avatarUri = data.getData();
203 if (xmppConnectionServiceBound) {
204 loadImageIntoPreview(this.avatarUri);
205 }
206 break;
207 case Crop.REQUEST_CROP:
208 this.avatarUri = Uri.fromFile(new File(getCacheDir(), "croppedAvatar"));
209 if (xmppConnectionServiceBound) {
210 loadImageIntoPreview(this.avatarUri);
211 }
212 break;
213 }
214 } else {
215 if (requestCode == Crop.REQUEST_CROP && data != null) {
216 Throwable throwable = Crop.getError(data);
217 if (throwable != null && throwable instanceof OutOfMemoryError) {
218 Toast.makeText(this,R.string.selection_too_large, Toast.LENGTH_SHORT).show();
219 }
220 }
221 }
222 }
223
224 @Override
225 protected void onBackendConnected() {
226 this.account = extractAccount(getIntent());
227 if (this.account != null) {
228 if (this.account.getXmppConnection() != null) {
229 this.support = this.account.getXmppConnection().getFeatures().pep();
230 }
231 if (this.avatarUri == null) {
232 if (this.account.getAvatar() != null
233 || this.defaultUri == null) {
234 this.avatar.setImageBitmap(avatarService().get(account, getPixel(192)));
235 if (this.defaultUri != null) {
236 this.avatar
237 .setOnLongClickListener(this.backToDefaultListener);
238 } else {
239 this.secondaryHint.setVisibility(View.INVISIBLE);
240 }
241 if (!support) {
242 this.hintOrWarning
243 .setTextColor(getWarningTextColor());
244 this.hintOrWarning
245 .setText(R.string.error_publish_avatar_no_server_support);
246 }
247 } else {
248 this.avatarUri = this.defaultUri;
249 loadImageIntoPreview(this.defaultUri);
250 this.secondaryHint.setVisibility(View.INVISIBLE);
251 }
252 } else {
253 loadImageIntoPreview(avatarUri);
254 }
255 String account;
256 if (Config.DOMAIN_LOCK != null) {
257 account = this.account.getJid().getLocalpart();
258 } else {
259 account = this.account.getJid().toBareJid().toString();
260 }
261 this.accountTextView.setText(account);
262 }
263 }
264
265 @Override
266 protected void onStart() {
267 super.onStart();
268 if (getIntent() != null) {
269 this.mInitialAccountSetup = getIntent().getBooleanExtra("setup", false);
270 }
271 if (this.mInitialAccountSetup) {
272 this.cancelButton.setText(R.string.skip);
273 }
274 }
275
276 protected void loadImageIntoPreview(Uri uri) {
277 Bitmap bm = null;
278 try {
279 bm = xmppConnectionService.getFileBackend().cropCenterSquare(uri, getPixel(192));
280 } catch (Exception e) {
281 e.printStackTrace();
282 }
283
284 if (bm == null) {
285 disablePublishButton();
286 this.hintOrWarning.setTextColor(getWarningTextColor());
287 this.hintOrWarning
288 .setText(R.string.error_publish_avatar_converting);
289 return;
290 }
291 this.avatar.setImageBitmap(bm);
292 if (support) {
293 enablePublishButton();
294 this.publishButton.setText(R.string.publish);
295 this.hintOrWarning.setText(R.string.publish_avatar_explanation);
296 this.hintOrWarning.setTextColor(getPrimaryTextColor());
297 } else {
298 disablePublishButton();
299 this.hintOrWarning.setTextColor(getWarningTextColor());
300 this.hintOrWarning
301 .setText(R.string.error_publish_avatar_no_server_support);
302 }
303 if (this.defaultUri != null && uri.equals(this.defaultUri)) {
304 this.secondaryHint.setVisibility(View.INVISIBLE);
305 this.avatar.setOnLongClickListener(null);
306 } else if (this.defaultUri != null) {
307 this.secondaryHint.setVisibility(View.VISIBLE);
308 this.avatar.setOnLongClickListener(this.backToDefaultListener);
309 }
310 }
311
312 protected void enablePublishButton() {
313 this.publishButton.setEnabled(true);
314 this.publishButton.setTextColor(getPrimaryTextColor());
315 }
316
317 protected void disablePublishButton() {
318 this.publishButton.setEnabled(false);
319 this.publishButton.setTextColor(getSecondaryTextColor());
320 }
321
322 public void refreshUiReal() {
323 //nothing to do. This Activity doesn't implement any listeners
324 }
325}