use of com.keylesspalace.tusky.view.RoundedTransformation in project Tusky by Vavassor.
the class NotificationMaker method make.
public static void make(final Context context, final int notifyId, Notification body) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
final SharedPreferences notificationPreferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
if (!filterNotification(preferences, body)) {
return;
}
String rawCurrentNotifications = notificationPreferences.getString("current", "[]");
JSONArray currentNotifications;
try {
currentNotifications = new JSONArray(rawCurrentNotifications);
} catch (JSONException e) {
currentNotifications = new JSONArray();
}
boolean alreadyContains = false;
for (int i = 0; i < currentNotifications.length(); i++) {
try {
if (currentNotifications.getString(i).equals(body.account.getDisplayName())) {
alreadyContains = true;
}
} catch (JSONException e) {
Log.d(TAG, Log.getStackTraceString(e));
}
}
if (!alreadyContains) {
currentNotifications.put(body.account.getDisplayName());
}
notificationPreferences.edit().putString("current", currentNotifications.toString()).commit();
Intent resultIntent = new Intent(context, MainActivity.class);
resultIntent.putExtra("tab_position", 1);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Intent deleteIntent = new Intent(context, NotificationClearBroadcastReceiver.class);
PendingIntent deletePendingIntent = PendingIntent.getBroadcast(context, 0, deleteIntent, PendingIntent.FLAG_CANCEL_CURRENT);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_notify).setContentIntent(resultPendingIntent).setDeleteIntent(deletePendingIntent).setDefaults(// So it doesn't ring twice, notify only in Target callback
0);
if (currentNotifications.length() == 1) {
builder.setContentTitle(titleForType(context, body)).setContentText(truncateWithEllipses(bodyForType(body), 40));
Target mTarget = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
builder.setLargeIcon(bitmap);
setupPreferences(preferences, builder);
((NotificationManager) (context.getSystemService(Context.NOTIFICATION_SERVICE))).notify(notifyId, builder.build());
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(context).load(body.account.avatar).placeholder(R.drawable.avatar_default).transform(new RoundedTransformation(7, 0)).into(mTarget);
} else {
setupPreferences(preferences, builder);
try {
builder.setContentTitle(String.format(context.getString(R.string.notification_title_summary), currentNotifications.length())).setContentText(truncateWithEllipses(joinNames(context, currentNotifications), 40));
} catch (JSONException e) {
Log.d(TAG, Log.getStackTraceString(e));
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setVisibility(android.app.Notification.VISIBILITY_PRIVATE);
builder.setCategory(android.app.Notification.CATEGORY_SOCIAL);
}
((NotificationManager) (context.getSystemService(Context.NOTIFICATION_SERVICE))).notify(notifyId, builder.build());
}
use of com.keylesspalace.tusky.view.RoundedTransformation in project Tusky by Vavassor.
the class StatusViewHolder method setAvatar.
private void setAvatar(String url) {
if (url.isEmpty()) {
return;
}
Context context = avatar.getContext();
Picasso.with(context).load(url).placeholder(R.drawable.avatar_default).error(R.drawable.avatar_error).transform(new RoundedTransformation(7, 0)).into(avatar);
}
use of com.keylesspalace.tusky.view.RoundedTransformation in project Tusky by tuskyapp.
the class StatusViewHolder method setAvatar.
@Override
void setAvatar(String url, @Nullable String rebloggedUrl) {
super.setAvatar(url, rebloggedUrl);
Context context = avatar.getContext();
boolean hasReblog = rebloggedUrl != null && !rebloggedUrl.isEmpty();
int padding = hasReblog ? Utils.dpToPx(context, 12) : 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
avatar.setPaddingRelative(0, 0, padding, padding);
} else {
avatar.setPadding(0, 0, padding, padding);
}
if (hasReblog) {
avatarReblog.setVisibility(View.VISIBLE);
Picasso.with(context).load(rebloggedUrl).placeholder(R.drawable.avatar_default).transform(new RoundedTransformation(25)).into(avatarReblog);
} else {
avatarReblog.setVisibility(View.GONE);
}
}
use of com.keylesspalace.tusky.view.RoundedTransformation in project Tusky by tuskyapp.
the class NotificationHelper method make.
/**
* Takes a given Mastodon notification and either creates a new Android notification or updates
* the state of the existing notification to reflect the new interaction.
*
* @param context to access application preferences and services
* @param body a new Mastodon notification
* @param account the account for which the notification should be shown
*/
public static void make(final Context context, Notification body, AccountEntity account) {
if (!filterNotification(account, body, context)) {
return;
}
String rawCurrentNotifications = account.getActiveNotifications();
JSONArray currentNotifications;
try {
currentNotifications = new JSONArray(rawCurrentNotifications);
} catch (JSONException e) {
currentNotifications = new JSONArray();
}
boolean alreadyContains = false;
for (int i = 0; i < currentNotifications.length(); i++) {
try {
if (currentNotifications.getString(i).equals(body.getAccount().getName())) {
alreadyContains = true;
}
} catch (JSONException e) {
Log.d(TAG, Log.getStackTraceString(e));
}
}
if (!alreadyContains) {
currentNotifications.put(body.getAccount().getName());
}
account.setActiveNotifications(currentNotifications.toString());
// no need to save account, this will be done in the calling function
Intent resultIntent = new Intent(context, MainActivity.class);
resultIntent.putExtra(ACCOUNT_ID, account.getId());
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent((int) account.getId(), PendingIntent.FLAG_UPDATE_CURRENT);
Intent deleteIntent = new Intent(context, NotificationClearBroadcastReceiver.class);
deleteIntent.putExtra(ACCOUNT_ID, account.getId());
PendingIntent deletePendingIntent = PendingIntent.getBroadcast(context, (int) account.getId(), deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context, getChannelId(account, body)).setSmallIcon(R.drawable.ic_notify).setContentIntent(resultPendingIntent).setDeleteIntent(deletePendingIntent).setColor(ContextCompat.getColor(context, (R.color.primary))).setDefaults(// So it doesn't ring twice, notify only in Target callback
0);
setupPreferences(account, builder);
if (currentNotifications.length() == 1) {
builder.setContentTitle(titleForType(context, body)).setContentText(bodyForType(body));
if (body.getType() == Notification.Type.MENTION) {
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(bodyForType(body)));
}
// load the avatar synchronously
Bitmap accountAvatar;
try {
accountAvatar = Picasso.with(context).load(body.getAccount().getAvatar()).transform(new RoundedTransformation(20)).get();
} catch (IOException e) {
Log.d(TAG, "error loading account avatar", e);
accountAvatar = BitmapFactory.decodeResource(context.getResources(), R.drawable.avatar_default);
}
builder.setLargeIcon(accountAvatar);
} else {
try {
String title = context.getString(R.string.notification_title_summary, currentNotifications.length());
String text = joinNames(context, currentNotifications);
builder.setContentTitle(title).setContentText(text);
} catch (JSONException e) {
Log.d(TAG, Log.getStackTraceString(e));
}
}
builder.setSubText(account.getFullName());
builder.setVisibility(NotificationCompat.VISIBILITY_PRIVATE);
builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
builder.setOnlyAlertOnce(true);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// noinspection ConstantConditions
notificationManager.notify((int) account.getId(), builder.build());
}
use of com.keylesspalace.tusky.view.RoundedTransformation in project Tusky by tuskyapp.
the class ComposeActivity method onCreate.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compose);
replyTextView = findViewById(R.id.reply_tv);
replyContentTextView = findViewById(R.id.reply_content_tv);
textEditor = findViewById(R.id.compose_edit_field);
mediaPreviewBar = findViewById(R.id.compose_media_preview_bar);
contentWarningBar = findViewById(R.id.compose_content_warning_bar);
contentWarningEditor = findViewById(R.id.field_content_warning);
charactersLeft = findViewById(R.id.characters_left);
floatingBtn = findViewById(R.id.floating_btn);
pickButton = findViewById(R.id.compose_photo_pick);
visibilityBtn = findViewById(R.id.action_toggle_visibility);
saveButton = findViewById(R.id.compose_save_draft);
hideMediaToggle = findViewById(R.id.action_hide_media);
postProgress = findViewById(R.id.postProgress);
// Setup the toolbar.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(null);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
Drawable closeIcon = AppCompatResources.getDrawable(this, R.drawable.ic_close_24dp);
ThemeUtils.setDrawableTint(this, closeIcon, R.attr.compose_close_button_tint);
actionBar.setHomeAsUpIndicator(closeIcon);
}
// setup the account image
final AccountEntity activeAccount = accountManager.getActiveAccount();
if (activeAccount != null) {
ImageView composeAvatar = findViewById(R.id.composeAvatar);
if (TextUtils.isEmpty(activeAccount.getProfilePictureUrl())) {
composeAvatar.setImageResource(R.drawable.avatar_default);
} else {
Picasso.with(this).load(activeAccount.getProfilePictureUrl()).transform(new RoundedTransformation(25)).error(R.drawable.avatar_default).placeholder(R.drawable.avatar_default).into(composeAvatar);
}
composeAvatar.setContentDescription(getString(R.string.compose_active_account_description, activeAccount.getFullName()));
} else {
// do not do anything when not logged in, activity will be finished in super.onCreate() anyway
return;
}
// Setup the interface buttons.
floatingBtn.setOnClickListener(v -> onSendClicked());
floatingBtn.setOnLongClickListener(v -> saveDraft());
pickButton.setOnClickListener(v -> openPickDialog());
visibilityBtn.setOnClickListener(v -> showComposeOptions());
saveButton.setOnClickListener(v -> saveDraft());
hideMediaToggle.setOnClickListener(v -> toggleHideMedia());
// fix a bug with autocomplete and some keyboards
int newInputType = textEditor.getInputType() & (textEditor.getInputType() ^ InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
textEditor.setInputType(newInputType);
/* Initialise all the state, or restore it from a previous run, to determine a "starting"
* state. */
Status.Visibility startingVisibility = Status.Visibility.UNKNOWN;
boolean startingHideText;
String startingContentWarning = null;
ArrayList<SavedQueuedMedia> savedMediaQueued = null;
if (savedInstanceState != null) {
showMarkSensitive = savedInstanceState.getBoolean("showMarkSensitive");
startingVisibility = Status.Visibility.byNum(savedInstanceState.getInt("statusVisibility", Status.Visibility.PUBLIC.getNum()));
statusMarkSensitive = savedInstanceState.getBoolean("statusMarkSensitive");
startingHideText = savedInstanceState.getBoolean("statusHideText");
// Keep these until everything needed to put them in the queue is finished initializing.
savedMediaQueued = savedInstanceState.getParcelableArrayList("savedMediaQueued");
// These are for restoring an in-progress commit content operation.
InputContentInfoCompat previousInputContentInfo = InputContentInfoCompat.wrap(savedInstanceState.getParcelable("commitContentInputContentInfo"));
int previousFlags = savedInstanceState.getInt("commitContentFlags");
if (previousInputContentInfo != null) {
onCommitContentInternal(previousInputContentInfo, previousFlags);
}
photoUploadUri = savedInstanceState.getParcelable("photoUploadUri");
} else {
showMarkSensitive = false;
statusMarkSensitive = false;
startingHideText = false;
photoUploadUri = null;
}
/* If the composer is started up as a reply to another post, override the "starting" state
* based on what the intent from the reply request passes. */
Intent intent = getIntent();
String[] mentionedUsernames = null;
ArrayList<String> loadedDraftMediaUris = null;
inReplyToId = null;
if (intent != null) {
if (startingVisibility == Status.Visibility.UNKNOWN) {
Status.Visibility replyVisibility = Status.Visibility.byNum(intent.getIntExtra(REPLY_VISIBILITY_EXTRA, Status.Visibility.UNKNOWN.getNum()));
if (replyVisibility != Status.Visibility.UNKNOWN) {
startingVisibility = replyVisibility;
} else {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
startingVisibility = Status.Visibility.byString(preferences.getString("defaultPostPrivacy", Status.Visibility.PUBLIC.serverString()));
}
}
inReplyToId = intent.getStringExtra(IN_REPLY_TO_ID_EXTRA);
mentionedUsernames = intent.getStringArrayExtra(MENTIONED_USERNAMES_EXTRA);
String contentWarning = intent.getStringExtra(CONTENT_WARNING_EXTRA);
if (contentWarning != null) {
startingHideText = !contentWarning.isEmpty();
if (startingHideText) {
startingContentWarning = contentWarning;
}
}
// If come from SavedTootActivity
String savedTootText = intent.getStringExtra(SAVED_TOOT_TEXT_EXTRA);
if (!TextUtils.isEmpty(savedTootText)) {
textEditor.append(savedTootText);
}
String savedJsonUrls = intent.getStringExtra(SAVED_JSON_URLS_EXTRA);
if (!TextUtils.isEmpty(savedJsonUrls)) {
// try to redo a list of media
loadedDraftMediaUris = new Gson().fromJson(savedJsonUrls, new TypeToken<ArrayList<String>>() {
}.getType());
}
int savedTootUid = intent.getIntExtra(SAVED_TOOT_UID_EXTRA, 0);
if (savedTootUid != 0) {
this.savedTootUid = savedTootUid;
}
if (intent.hasExtra(REPLYING_STATUS_AUTHOR_USERNAME_EXTRA)) {
replyTextView.setVisibility(View.VISIBLE);
String username = intent.getStringExtra(REPLYING_STATUS_AUTHOR_USERNAME_EXTRA);
replyTextView.setText(getString(R.string.replying_to, username));
replyTextView.setOnClickListener(v -> {
if (replyContentTextView.getVisibility() != View.VISIBLE) {
replyContentTextView.setVisibility(View.VISIBLE);
} else {
replyContentTextView.setVisibility(View.GONE);
}
});
}
if (intent.hasExtra(REPLYING_STATUS_CONTENT_EXTRA)) {
replyContentTextView.setText(intent.getStringExtra(REPLYING_STATUS_CONTENT_EXTRA));
}
}
// After the starting state is finalised, the interface can be set to reflect this state.
setStatusVisibility(startingVisibility);
postProgress.setVisibility(View.INVISIBLE);
updateHideMediaToggleColor();
updateVisibleCharactersLeft();
// Setup the main text field.
// new String[] { "image/gif", "image/webp" }
setEditTextMimeTypes();
final int mentionColour = ThemeUtils.getColor(this, R.attr.compose_mention_color);
SpanUtils.highlightSpans(textEditor.getText(), mentionColour);
textEditor.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
updateVisibleCharactersLeft();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable editable) {
SpanUtils.highlightSpans(editable, mentionColour);
}
});
textEditor.setAdapter(new MentionAutoCompleteAdapter(this, R.layout.item_autocomplete, this));
textEditor.setTokenizer(new MentionTokenizer());
// Add any mentions to the text field when a reply is first composed.
if (mentionedUsernames != null) {
StringBuilder builder = new StringBuilder();
for (String name : mentionedUsernames) {
builder.append('@');
builder.append(name);
builder.append(' ');
}
textEditor.setText(builder);
textEditor.setSelection(textEditor.length());
}
// Initialise the content warning editor.
contentWarningEditor.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) {
updateVisibleCharactersLeft();
}
@Override
public void afterTextChanged(Editable s) {
}
});
showContentWarning(startingHideText);
if (startingContentWarning != null) {
contentWarningEditor.setText(startingContentWarning);
}
// Initialise the empty media queue state.
waitForMediaLatch = new CountUpDownLatch();
statusAlreadyInFlight = false;
// These can only be added after everything affected by the media queue is initialized.
if (!ListUtils.isEmpty(loadedDraftMediaUris)) {
for (String uriString : loadedDraftMediaUris) {
Uri uri = Uri.parse(uriString);
long mediaSize = MediaUtils.getMediaSize(getContentResolver(), uri);
pickMedia(uri, mediaSize);
}
} else if (savedMediaQueued != null) {
for (SavedQueuedMedia item : savedMediaQueued) {
Bitmap preview = MediaUtils.getImageThumbnail(getContentResolver(), item.uri, THUMBNAIL_SIZE);
addMediaToQueue(item.type, preview, item.uri, item.mediaSize, item.readyStage, item.description);
}
} else if (intent != null && savedInstanceState == null) {
/* Get incoming images being sent through a share action from another app. Only do this
* when savedInstanceState is null, otherwise both the images from the intent and the
* instance state will be re-queued. */
String type = intent.getType();
if (type != null) {
if (type.startsWith("image/")) {
List<Uri> uriList = new ArrayList<>();
if (intent.getAction() != null) {
switch(intent.getAction()) {
case Intent.ACTION_SEND:
{
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (uri != null) {
uriList.add(uri);
}
break;
}
case Intent.ACTION_SEND_MULTIPLE:
{
ArrayList<Uri> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (list != null) {
for (Uri uri : list) {
if (uri != null) {
uriList.add(uri);
}
}
}
break;
}
}
}
for (Uri uri : uriList) {
long mediaSize = MediaUtils.getMediaSize(getContentResolver(), uri);
pickMedia(uri, mediaSize);
}
} else if (type.equals("text/plain")) {
String action = intent.getAction();
if (action != null && action.equals(Intent.ACTION_SEND)) {
String text = intent.getStringExtra(Intent.EXTRA_TEXT);
if (text != null) {
int start = Math.max(textEditor.getSelectionStart(), 0);
int end = Math.max(textEditor.getSelectionEnd(), 0);
int left = Math.min(start, end);
int right = Math.max(start, end);
textEditor.getText().replace(left, right, text, 0, text.length());
}
}
}
}
}
textEditor.requestFocus();
}
Aggregations