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