1package eu.siacs.conversations.ui;
2
3import android.content.Intent;
4import android.graphics.Bitmap;
5import android.net.Uri;
6import android.os.Bundle;
7import android.support.annotation.StringRes;
8import android.util.Log;
9import android.view.View;
10import android.view.View.OnLongClickListener;
11import android.widget.Button;
12import android.widget.ImageView;
13import android.widget.TextView;
14import android.widget.Toast;
15
16import com.theartofdev.edmodo.cropper.CropImage;
17
18import eu.siacs.conversations.Config;
19import eu.siacs.conversations.R;
20import eu.siacs.conversations.entities.Account;
21import eu.siacs.conversations.services.XmppConnectionService;
22import eu.siacs.conversations.ui.interfaces.OnAvatarPublication;
23import eu.siacs.conversations.utils.PhoneHelper;
24
25public class PublishProfilePictureActivity extends XmppActivity implements XmppConnectionService.OnAccountUpdate, OnAvatarPublication {
26
27 private ImageView avatar;
28 private TextView hintOrWarning;
29 private TextView secondaryHint;
30 private Button cancelButton;
31 private Button publishButton;
32 private Uri avatarUri;
33 private Uri defaultUri;
34 private Account account;
35 private boolean support = false;
36 private boolean publishing = false;
37 private OnLongClickListener backToDefaultListener = new OnLongClickListener() {
38
39 @Override
40 public boolean onLongClick(View v) {
41 avatarUri = defaultUri;
42 loadImageIntoPreview(defaultUri);
43 return true;
44 }
45 };
46 private boolean mInitialAccountSetup;
47
48 @Override
49 public void onAvatarPublicationSucceeded() {
50 runOnUiThread(() -> {
51 if (mInitialAccountSetup) {
52 Intent intent = new Intent(getApplicationContext(), StartConversationActivity.class);
53 WelcomeActivity.addInviteUri(intent, getIntent());
54 intent.putExtra("init", true);
55 startActivity(intent);
56 }
57 Toast.makeText(PublishProfilePictureActivity.this,
58 R.string.avatar_has_been_published,
59 Toast.LENGTH_SHORT).show();
60 finish();
61 });
62 }
63
64 @Override
65 public void onAvatarPublicationFailed(int res) {
66 runOnUiThread(() -> {
67 hintOrWarning.setText(res);
68 hintOrWarning.setTextColor(getWarningTextColor());
69 hintOrWarning.setVisibility(View.VISIBLE);
70 publishing = false;
71 togglePublishButton(true, R.string.publish);
72 });
73 }
74
75 @Override
76 public void onCreate(Bundle savedInstanceState) {
77 super.onCreate(savedInstanceState);
78 setContentView(R.layout.activity_publish_profile_picture);
79 setSupportActionBar(findViewById(R.id.toolbar));
80 configureActionBar(getSupportActionBar());
81
82 this.avatar = findViewById(R.id.account_image);
83 this.cancelButton = findViewById(R.id.cancel_button);
84 this.publishButton = findViewById(R.id.publish_button);
85 this.hintOrWarning = findViewById(R.id.hint_or_warning);
86 this.secondaryHint = findViewById(R.id.secondary_hint);
87 this.publishButton.setOnClickListener(v -> {
88 if (avatarUri != null) {
89 publishing = true;
90 togglePublishButton(false, R.string.publishing);
91 xmppConnectionService.publishAvatar(account, avatarUri, this);
92 }
93 });
94 this.cancelButton.setOnClickListener(v -> {
95 if (mInitialAccountSetup) {
96 Intent intent = new Intent(getApplicationContext(), StartConversationActivity.class);
97 if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) {
98 WelcomeActivity.addInviteUri(intent, getIntent());
99 intent.putExtra("init", true);
100 }
101 startActivity(intent);
102 }
103 finish();
104 });
105 this.avatar.setOnClickListener(v -> chooseAvatar());
106 this.defaultUri = PhoneHelper.getProfilePictureUri(getApplicationContext());
107 }
108
109
110 @Override
111 public void onActivityResult(int requestCode, int resultCode, Intent data) {
112 if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
113 CropImage.ActivityResult result = CropImage.getActivityResult(data);
114 if (resultCode == RESULT_OK) {
115 this.avatarUri = result.getUri();
116 if (xmppConnectionServiceBound) {
117 loadImageIntoPreview(this.avatarUri);
118 }
119 } else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
120 Exception error = result.getError();
121 if (error != null) {
122 Toast.makeText(this, error.getMessage(), Toast.LENGTH_SHORT).show();
123 }
124 }
125 }
126 }
127
128 private void chooseAvatar() {
129 CropImage.activity()
130 .setOutputCompressFormat(Bitmap.CompressFormat.PNG)
131 .setAspectRatio(1, 1)
132 .setMinCropResultSize(Config.AVATAR_SIZE, Config.AVATAR_SIZE)
133 .start(this);
134 }
135
136 @Override
137 protected void onBackendConnected() {
138 this.account = extractAccount(getIntent());
139 if (this.account != null) {
140 reloadAvatar();
141 }
142 }
143
144 private void reloadAvatar() {
145 this.support = this.account.getXmppConnection() != null && this.account.getXmppConnection().getFeatures().pep();
146 if (this.avatarUri == null) {
147 if (this.account.getAvatar() != null || this.defaultUri == null) {
148 loadImageIntoPreview(null);
149 } else {
150 this.avatarUri = this.defaultUri;
151 loadImageIntoPreview(this.defaultUri);
152 }
153 } else {
154 loadImageIntoPreview(avatarUri);
155 }
156 }
157
158 @Override
159 protected void onStart() {
160 super.onStart();
161 if (getIntent() != null) {
162 this.mInitialAccountSetup = getIntent().getBooleanExtra("setup", false);
163 }
164 if (this.mInitialAccountSetup) {
165 this.cancelButton.setText(R.string.skip);
166 }
167 }
168
169 protected void loadImageIntoPreview(Uri uri) {
170
171 Bitmap bm = null;
172 if (uri == null) {
173 bm = avatarService().get(account, (int) getResources().getDimension(R.dimen.publish_avatar_size));
174 } else {
175 try {
176 bm = xmppConnectionService.getFileBackend().cropCenterSquare(uri, (int) getResources().getDimension(R.dimen.publish_avatar_size));
177 } catch (Exception e) {
178 Log.d(Config.LOGTAG, "unable to load bitmap into image view", e);
179 }
180 }
181
182 if (bm == null) {
183 togglePublishButton(false, R.string.publish);
184 this.hintOrWarning.setVisibility(View.VISIBLE);
185 this.hintOrWarning.setTextColor(getWarningTextColor());
186 this.hintOrWarning.setText(R.string.error_publish_avatar_converting);
187 return;
188 }
189 this.avatar.setImageBitmap(bm);
190 if (support) {
191 togglePublishButton(uri != null, R.string.publish);
192 this.hintOrWarning.setVisibility(View.INVISIBLE);
193 } else {
194 togglePublishButton(false, R.string.publish);
195 this.hintOrWarning.setVisibility(View.VISIBLE);
196 this.hintOrWarning.setTextColor(getWarningTextColor());
197 if (account.getStatus() == Account.State.ONLINE) {
198 this.hintOrWarning.setText(R.string.error_publish_avatar_no_server_support);
199 } else {
200 this.hintOrWarning.setText(R.string.error_publish_avatar_offline);
201 }
202 }
203 if (this.defaultUri == null || this.defaultUri.equals(uri)) {
204 this.secondaryHint.setVisibility(View.INVISIBLE);
205 this.avatar.setOnLongClickListener(null);
206 } else if (this.defaultUri != null) {
207 this.secondaryHint.setVisibility(View.VISIBLE);
208 this.avatar.setOnLongClickListener(this.backToDefaultListener);
209 }
210 }
211
212 protected void togglePublishButton(boolean enabled, @StringRes int res) {
213 final boolean status = enabled && !publishing;
214 this.publishButton.setText(publishing ? R.string.publishing : res);
215 this.publishButton.setEnabled(status);
216 }
217
218 public void refreshUiReal() {
219 if (this.account != null) {
220 reloadAvatar();
221 }
222 }
223
224 @Override
225 public void onAccountUpdate() {
226 refreshUi();
227 }
228
229}