Loading app/src/main/java/app/fedilab/android/mastodon/activities/EditProfileActivity.java +91 −18 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.text.Html; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -45,10 +46,13 @@ import java.util.Objects; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.BuildConfig; import app.fedilab.android.R; import app.fedilab.android.databinding.AccountFeaturedHashtagItemBinding; import app.fedilab.android.databinding.AccountFieldItemBinding; import app.fedilab.android.databinding.ActivityEditProfileBinding; import app.fedilab.android.mastodon.client.entities.api.Account; import app.fedilab.android.mastodon.client.entities.api.FeaturedTag; import app.fedilab.android.mastodon.client.entities.api.Field; import app.fedilab.android.mastodon.client.entities.api.Tag; import app.fedilab.android.mastodon.client.entities.app.CachedBundle; import app.fedilab.android.mastodon.exception.DBException; import app.fedilab.android.mastodon.helper.Helper; Loading @@ -62,6 +66,8 @@ public class EditProfileActivity extends BaseBarActivity { public static final int PICK_MEDIA_HEADER = 5706; private ActivityEditProfileBinding binding; private AccountsVM accountsVM; private static final int MAX_FIELDS = 4; private static final int MAX_FEATURED_HASHTAGS = 10; @SuppressLint("ClickableViewAccessibility") @Override Loading @@ -87,8 +93,9 @@ public class EditProfileActivity extends BaseBarActivity { return false; }); accountsVM = new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class); new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class).getConnectedAccount(BaseMainActivity.currentInstance, BaseMainActivity.currentToken) accountsVM.getConnectedAccount(BaseMainActivity.currentInstance, BaseMainActivity.currentToken) .observe(EditProfileActivity.this, account -> { if (account != null) { Helper.setCurrentAccountMastodonAccount(EditProfileActivity.this, account); Loading @@ -97,9 +104,10 @@ public class EditProfileActivity extends BaseBarActivity { Helper.sendToastMessage(getApplication(), Helper.RECEIVE_TOAST_TYPE_ERROR, getString(R.string.toast_error)); } }); } } @SuppressWarnings("deprecation") private void initializeView() { //Hydrate values Loading @@ -113,6 +121,68 @@ public class EditProfileActivity extends BaseBarActivity { else bio = Html.fromHtml(Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.note).toString(); binding.bio.setText(bio); accountsVM.getFeaturedTagsSuggestions(BaseMainActivity.currentInstance, BaseMainActivity.currentToken).observe(this, featuredTags -> { StringBuilder text = new StringBuilder(getString(R.string.no_feature_hashtag_suggestion)); if(featuredTags != null && !featuredTags.isEmpty()) { text = new StringBuilder(); for (Tag tag : featuredTags) { text.append(String.format("#%s ", tag.name)); } } binding.featuredHashtagsSuggestions.setText(text); }); accountsVM.getAccountFeaturedTags(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.id).observe(this, featuredTags -> { if(featuredTags != null && !featuredTags.isEmpty()) { for (FeaturedTag featuredTag : featuredTags) { AccountFeaturedHashtagItemBinding featuredHashtagItemBinding = AccountFeaturedHashtagItemBinding.inflate(getLayoutInflater()); featuredHashtagItemBinding.name.setText(featuredTag.name); featuredHashtagItemBinding.remove.setOnClickListener(v -> { AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this); deleteConfirm.setTitle(getString(R.string.delete_featured_hashtag)); deleteConfirm.setMessage(getString(R.string.delete_featured_hashtag_confirm)); deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> { ((ViewGroup)featuredHashtagItemBinding.getRoot().getParent()).removeView(featuredHashtagItemBinding.getRoot()); if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) { binding.addFeaturedHashtags.setVisibility(View.GONE); } else { binding.addFeaturedHashtags.setVisibility(View.VISIBLE); } dialog.dismiss(); }); deleteConfirm.create().show(); }); binding.featuredHashtagsContainer.addView(featuredHashtagItemBinding.getRoot()); } } binding.addFeaturedHashtags.setOnClickListener(view -> { AccountFeaturedHashtagItemBinding featuredHashtagItemBinding = AccountFeaturedHashtagItemBinding.inflate(getLayoutInflater()); featuredHashtagItemBinding.remove.setOnClickListener(v -> { AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this); deleteConfirm.setTitle(getString(R.string.delete_featured_hashtag)); deleteConfirm.setMessage(getString(R.string.delete_featured_hashtag_confirm)); deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> { ((ViewGroup)featuredHashtagItemBinding.getRoot().getParent()).removeView(featuredHashtagItemBinding.getRoot()); if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) { binding.addFeaturedHashtags.setVisibility(View.GONE); } else { binding.addFeaturedHashtags.setVisibility(View.VISIBLE); } dialog.dismiss(); }); deleteConfirm.create().show(); }); binding.featuredHashtagsContainer.addView(featuredHashtagItemBinding.getRoot()); if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) { binding.addFeaturedHashtags.setVisibility(View.GONE); } else { binding.addFeaturedHashtags.setVisibility(View.VISIBLE); } }); }); if (Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source != null) { binding.sensitive.setChecked(Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source.sensitive); switch (Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source.privacy) { Loading @@ -135,7 +205,7 @@ public class EditProfileActivity extends BaseBarActivity { binding.unlocked.setChecked(true); } List<Field> fields = Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.fields; if (fields != null && fields.size() > 0) { if (fields != null && !fields.isEmpty()) { for (Field field : fields) { AccountFieldItemBinding fieldItemBinding = AccountFieldItemBinding.inflate(getLayoutInflater()); fieldItemBinding.name.setText(field.name); Loading @@ -151,11 +221,11 @@ public class EditProfileActivity extends BaseBarActivity { deleteConfirm.setMessage(getString(R.string.delete_field_confirm)); deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> { binding.fieldsContainer.removeView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() < 4) { binding.fieldsContainer.setVisibility(View.VISIBLE); ((ViewGroup)fieldItemBinding.getRoot().getParent()).removeView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) { binding.addField.setVisibility(View.GONE); } else { binding.fieldsContainer.setVisibility(View.GONE); binding.addField.setVisibility(View.VISIBLE); } dialog.dismiss(); }); Loading @@ -163,7 +233,11 @@ public class EditProfileActivity extends BaseBarActivity { }); binding.fieldsContainer.addView(fieldItemBinding.getRoot()); } if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) { binding.addField.setVisibility(View.GONE); } else { binding.addField.setVisibility(View.VISIBLE); } } binding.addField.setOnClickListener(view -> { AccountFieldItemBinding fieldItemBinding = AccountFieldItemBinding.inflate(getLayoutInflater()); Loading @@ -173,25 +247,24 @@ public class EditProfileActivity extends BaseBarActivity { deleteConfirm.setMessage(getString(R.string.delete_field_confirm)); deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> { binding.fieldsContainer.removeView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() < 4) { binding.fieldsContainer.setVisibility(View.VISIBLE); ((ViewGroup)fieldItemBinding.getRoot().getParent()).removeView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) { binding.addField.setVisibility(View.GONE); } else { binding.fieldsContainer.setVisibility(View.GONE); binding.addField.setVisibility(View.VISIBLE); } dialog.dismiss(); }); deleteConfirm.create().show(); }); binding.fieldsContainer.addView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() >= 4) { if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) { binding.addField.setVisibility(View.GONE); } else { binding.addField.setVisibility(View.VISIBLE); } }); //Actions with the activity accountsVM = new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class); binding.headerSelect.setOnClickListener(view -> startActivityForResult(prepareIntent(), EditProfileActivity.PICK_MEDIA_HEADER)); binding.avatarSelect.setOnClickListener(view -> startActivityForResult(prepareIntent(), EditProfileActivity.PICK_MEDIA_AVATAR)); Loading Loading @@ -280,7 +353,7 @@ public class EditProfileActivity extends BaseBarActivity { intent.setType("*/*"); String[] mimetypes; long max_size = -1; if (instanceInfo.getMimeTypeImage().size() > 0) { if (!instanceInfo.getMimeTypeImage().isEmpty()) { mimetypes = instanceInfo.getMimeTypeImage().toArray(new String[0]); max_size = instanceInfo.configuration.media_attachments.image_size_limit; } else { Loading app/src/main/res/layouts/mastodon/layout/account_featured_hashtag_item.xml 0 → 100644 +63 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?><!-- Copyright 2025 Thomas Schneider This file is a part of Fedilab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fedilab; if not, see <http://www.gnu.org/licenses> --> <com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipChildren="false" android:clipToPadding="false" android:layout_marginTop="6dp" app:cardElevation="0dp" app:strokeWidth="0dp"> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:gravity="center_vertical" android:orientation="horizontal"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" tools:text="@tools:sample/first_names" /> <com.google.android.material.button.MaterialButton android:id="@+id/remove" style="@style/Widget.Material3.Button.OutlinedButton.Icon" android:layout_width="36dp" android:layout_height="36dp" android:contentDescription="@string/delete_field" android:insetTop="0dp" android:insetBottom="0dp" android:padding="0dp" android:textColor="?colorError" app:icon="@drawable/ic_compose_attachment_remove" app:iconGravity="textStart" app:iconPadding="0dp" app:iconTint="?colorError" app:layout_constraintStart_toStartOf="@id/banner_pp" app:layout_constraintTop_toTopOf="@id/banner_pp" app:strokeColor="?colorError" /> </androidx.appcompat.widget.LinearLayoutCompat> </com.google.android.material.card.MaterialCardView> app/src/main/res/layouts/mastodon/layout/activity_edit_profile.xml +66 −2 Original line number Diff line number Diff line Loading @@ -161,6 +161,16 @@ app:layout_constraintTop_toBottomOf="@id/acct" tools:text="@tools:sample/lorem/random" /> <com.google.android.material.textview.MaterialTextView android:id="@+id/fields_label" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="12dp" android:layout_marginTop="12dp" android:text="@string/fields_title" android:textAppearance="@style/TextAppearance.Material3.BodyMedium" app:layout_constraintTop_toBottomOf="@id/bio" /> <androidx.appcompat.widget.LinearLayoutCompat android:id="@+id/fields" android:layout_width="match_parent" Loading @@ -168,7 +178,7 @@ android:layout_marginHorizontal="12dp" android:layout_marginTop="12dp" android:orientation="vertical" app:layout_constraintTop_toBottomOf="@id/bio"> app:layout_constraintTop_toBottomOf="@id/fields_label"> <androidx.appcompat.widget.LinearLayoutCompat android:id="@+id/fields_container" Loading @@ -188,6 +198,60 @@ </androidx.appcompat.widget.LinearLayoutCompat> <com.google.android.material.textview.MaterialTextView android:id="@+id/featured_hashtags_label" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="12dp" android:layout_marginTop="12dp" android:text="@string/featured_hashtags_title" android:textAppearance="@style/TextAppearance.Material3.BodyMedium" app:layout_constraintTop_toBottomOf="@id/fields" /> <androidx.appcompat.widget.LinearLayoutCompat android:id="@+id/featured_hashtags" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="12dp" android:layout_marginTop="12dp" android:orientation="vertical" app:layout_constraintTop_toBottomOf="@id/featured_hashtags_label"> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <com.google.android.material.textview.MaterialTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/Suggestions"/> <com.google.android.material.textview.MaterialTextView android:id="@+id/featured_hashtags_suggestions" android:layout_marginStart="10dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/Suggestions"/> </androidx.appcompat.widget.LinearLayoutCompat> <androidx.appcompat.widget.LinearLayoutCompat android:layout_marginTop="5dp" android:id="@+id/featured_hashtags_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" /> <com.google.android.material.button.MaterialButton android:id="@+id/add_featured_hashtags" style="@style/Widget.Material3.Button.OutlinedButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" android:layout_marginVertical="6dp" android:text="@string/add_featured_hashtag" app:icon="@drawable/ic_baseline_add_24" /> </androidx.appcompat.widget.LinearLayoutCompat> <com.google.android.material.textview.MaterialTextView android:id="@+id/visibility_label" android:layout_width="match_parent" Loading @@ -196,7 +260,7 @@ android:layout_marginTop="12dp" android:text="@string/toots_visibility_title" android:textAppearance="@style/TextAppearance.Material3.BodyMedium" app:layout_constraintTop_toBottomOf="@id/fields" /> app:layout_constraintTop_toBottomOf="@id/featured_hashtags" /> <com.google.android.material.button.MaterialButtonToggleGroup android:id="@+id/visibility_group" Loading app/src/main/res/values/strings.xml +6 −0 Original line number Diff line number Diff line Loading @@ -732,13 +732,19 @@ <string name="interactions">Interactions</string> <string name="add_filter">Add filter</string> <string name="add_field">Add Field</string> <string name="add_featured_hashtag">Add Featured Hashtag</string> <string name="no_feature_hashtag_suggestion">No suggestions for featured hashtags!</string> <string name="unlocked">Unlocked</string> <string name="locked">Locked</string> <string name="save_changes">Save changes</string> <string name="set_bot_content">Bot account</string> <string name="fields_title">Add or remove fields</string> <string name="featured_hashtags_title">Add or remove featured hashtags</string> <string name="set_discoverable_content">Account discoverable</string> <string name="delete_field">Delete field</string> <string name="delete_featured_hashtag">Delete featured hashtag</string> <string name="delete_field_confirm">Are you sure you want to delete that field?</string> <string name="delete_featured_hashtag_confirm">Are you sure you want to delete that featured hashtag?</string> <string name="profiled_updated">Profile has been updated!</string> <string name="not_valid_list_name">List name is not valid!</string> <string name="no_account_in_list">No accounts found for this list!</string> Loading Loading
app/src/main/java/app/fedilab/android/mastodon/activities/EditProfileActivity.java +91 −18 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.text.Html; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -45,10 +46,13 @@ import java.util.Objects; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.BuildConfig; import app.fedilab.android.R; import app.fedilab.android.databinding.AccountFeaturedHashtagItemBinding; import app.fedilab.android.databinding.AccountFieldItemBinding; import app.fedilab.android.databinding.ActivityEditProfileBinding; import app.fedilab.android.mastodon.client.entities.api.Account; import app.fedilab.android.mastodon.client.entities.api.FeaturedTag; import app.fedilab.android.mastodon.client.entities.api.Field; import app.fedilab.android.mastodon.client.entities.api.Tag; import app.fedilab.android.mastodon.client.entities.app.CachedBundle; import app.fedilab.android.mastodon.exception.DBException; import app.fedilab.android.mastodon.helper.Helper; Loading @@ -62,6 +66,8 @@ public class EditProfileActivity extends BaseBarActivity { public static final int PICK_MEDIA_HEADER = 5706; private ActivityEditProfileBinding binding; private AccountsVM accountsVM; private static final int MAX_FIELDS = 4; private static final int MAX_FEATURED_HASHTAGS = 10; @SuppressLint("ClickableViewAccessibility") @Override Loading @@ -87,8 +93,9 @@ public class EditProfileActivity extends BaseBarActivity { return false; }); accountsVM = new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class); new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class).getConnectedAccount(BaseMainActivity.currentInstance, BaseMainActivity.currentToken) accountsVM.getConnectedAccount(BaseMainActivity.currentInstance, BaseMainActivity.currentToken) .observe(EditProfileActivity.this, account -> { if (account != null) { Helper.setCurrentAccountMastodonAccount(EditProfileActivity.this, account); Loading @@ -97,9 +104,10 @@ public class EditProfileActivity extends BaseBarActivity { Helper.sendToastMessage(getApplication(), Helper.RECEIVE_TOAST_TYPE_ERROR, getString(R.string.toast_error)); } }); } } @SuppressWarnings("deprecation") private void initializeView() { //Hydrate values Loading @@ -113,6 +121,68 @@ public class EditProfileActivity extends BaseBarActivity { else bio = Html.fromHtml(Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.note).toString(); binding.bio.setText(bio); accountsVM.getFeaturedTagsSuggestions(BaseMainActivity.currentInstance, BaseMainActivity.currentToken).observe(this, featuredTags -> { StringBuilder text = new StringBuilder(getString(R.string.no_feature_hashtag_suggestion)); if(featuredTags != null && !featuredTags.isEmpty()) { text = new StringBuilder(); for (Tag tag : featuredTags) { text.append(String.format("#%s ", tag.name)); } } binding.featuredHashtagsSuggestions.setText(text); }); accountsVM.getAccountFeaturedTags(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.id).observe(this, featuredTags -> { if(featuredTags != null && !featuredTags.isEmpty()) { for (FeaturedTag featuredTag : featuredTags) { AccountFeaturedHashtagItemBinding featuredHashtagItemBinding = AccountFeaturedHashtagItemBinding.inflate(getLayoutInflater()); featuredHashtagItemBinding.name.setText(featuredTag.name); featuredHashtagItemBinding.remove.setOnClickListener(v -> { AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this); deleteConfirm.setTitle(getString(R.string.delete_featured_hashtag)); deleteConfirm.setMessage(getString(R.string.delete_featured_hashtag_confirm)); deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> { ((ViewGroup)featuredHashtagItemBinding.getRoot().getParent()).removeView(featuredHashtagItemBinding.getRoot()); if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) { binding.addFeaturedHashtags.setVisibility(View.GONE); } else { binding.addFeaturedHashtags.setVisibility(View.VISIBLE); } dialog.dismiss(); }); deleteConfirm.create().show(); }); binding.featuredHashtagsContainer.addView(featuredHashtagItemBinding.getRoot()); } } binding.addFeaturedHashtags.setOnClickListener(view -> { AccountFeaturedHashtagItemBinding featuredHashtagItemBinding = AccountFeaturedHashtagItemBinding.inflate(getLayoutInflater()); featuredHashtagItemBinding.remove.setOnClickListener(v -> { AlertDialog.Builder deleteConfirm = new MaterialAlertDialogBuilder(EditProfileActivity.this); deleteConfirm.setTitle(getString(R.string.delete_featured_hashtag)); deleteConfirm.setMessage(getString(R.string.delete_featured_hashtag_confirm)); deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> { ((ViewGroup)featuredHashtagItemBinding.getRoot().getParent()).removeView(featuredHashtagItemBinding.getRoot()); if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) { binding.addFeaturedHashtags.setVisibility(View.GONE); } else { binding.addFeaturedHashtags.setVisibility(View.VISIBLE); } dialog.dismiss(); }); deleteConfirm.create().show(); }); binding.featuredHashtagsContainer.addView(featuredHashtagItemBinding.getRoot()); if (binding.featuredHashtagsContainer.getChildCount() >= MAX_FEATURED_HASHTAGS) { binding.addFeaturedHashtags.setVisibility(View.GONE); } else { binding.addFeaturedHashtags.setVisibility(View.VISIBLE); } }); }); if (Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source != null) { binding.sensitive.setChecked(Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source.sensitive); switch (Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.source.privacy) { Loading @@ -135,7 +205,7 @@ public class EditProfileActivity extends BaseBarActivity { binding.unlocked.setChecked(true); } List<Field> fields = Helper.getCurrentAccount(EditProfileActivity.this).mastodon_account.fields; if (fields != null && fields.size() > 0) { if (fields != null && !fields.isEmpty()) { for (Field field : fields) { AccountFieldItemBinding fieldItemBinding = AccountFieldItemBinding.inflate(getLayoutInflater()); fieldItemBinding.name.setText(field.name); Loading @@ -151,11 +221,11 @@ public class EditProfileActivity extends BaseBarActivity { deleteConfirm.setMessage(getString(R.string.delete_field_confirm)); deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> { binding.fieldsContainer.removeView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() < 4) { binding.fieldsContainer.setVisibility(View.VISIBLE); ((ViewGroup)fieldItemBinding.getRoot().getParent()).removeView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) { binding.addField.setVisibility(View.GONE); } else { binding.fieldsContainer.setVisibility(View.GONE); binding.addField.setVisibility(View.VISIBLE); } dialog.dismiss(); }); Loading @@ -163,7 +233,11 @@ public class EditProfileActivity extends BaseBarActivity { }); binding.fieldsContainer.addView(fieldItemBinding.getRoot()); } if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) { binding.addField.setVisibility(View.GONE); } else { binding.addField.setVisibility(View.VISIBLE); } } binding.addField.setOnClickListener(view -> { AccountFieldItemBinding fieldItemBinding = AccountFieldItemBinding.inflate(getLayoutInflater()); Loading @@ -173,25 +247,24 @@ public class EditProfileActivity extends BaseBarActivity { deleteConfirm.setMessage(getString(R.string.delete_field_confirm)); deleteConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); deleteConfirm.setPositiveButton(R.string.delete, (dialog, which) -> { binding.fieldsContainer.removeView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() < 4) { binding.fieldsContainer.setVisibility(View.VISIBLE); ((ViewGroup)fieldItemBinding.getRoot().getParent()).removeView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) { binding.addField.setVisibility(View.GONE); } else { binding.fieldsContainer.setVisibility(View.GONE); binding.addField.setVisibility(View.VISIBLE); } dialog.dismiss(); }); deleteConfirm.create().show(); }); binding.fieldsContainer.addView(fieldItemBinding.getRoot()); if (binding.fieldsContainer.getChildCount() >= 4) { if (binding.fieldsContainer.getChildCount() >= MAX_FIELDS) { binding.addField.setVisibility(View.GONE); } else { binding.addField.setVisibility(View.VISIBLE); } }); //Actions with the activity accountsVM = new ViewModelProvider(EditProfileActivity.this).get(AccountsVM.class); binding.headerSelect.setOnClickListener(view -> startActivityForResult(prepareIntent(), EditProfileActivity.PICK_MEDIA_HEADER)); binding.avatarSelect.setOnClickListener(view -> startActivityForResult(prepareIntent(), EditProfileActivity.PICK_MEDIA_AVATAR)); Loading Loading @@ -280,7 +353,7 @@ public class EditProfileActivity extends BaseBarActivity { intent.setType("*/*"); String[] mimetypes; long max_size = -1; if (instanceInfo.getMimeTypeImage().size() > 0) { if (!instanceInfo.getMimeTypeImage().isEmpty()) { mimetypes = instanceInfo.getMimeTypeImage().toArray(new String[0]); max_size = instanceInfo.configuration.media_attachments.image_size_limit; } else { Loading
app/src/main/res/layouts/mastodon/layout/account_featured_hashtag_item.xml 0 → 100644 +63 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?><!-- Copyright 2025 Thomas Schneider This file is a part of Fedilab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fedilab; if not, see <http://www.gnu.org/licenses> --> <com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipChildren="false" android:clipToPadding="false" android:layout_marginTop="6dp" app:cardElevation="0dp" app:strokeWidth="0dp"> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:gravity="center_vertical" android:orientation="horizontal"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center_vertical" tools:text="@tools:sample/first_names" /> <com.google.android.material.button.MaterialButton android:id="@+id/remove" style="@style/Widget.Material3.Button.OutlinedButton.Icon" android:layout_width="36dp" android:layout_height="36dp" android:contentDescription="@string/delete_field" android:insetTop="0dp" android:insetBottom="0dp" android:padding="0dp" android:textColor="?colorError" app:icon="@drawable/ic_compose_attachment_remove" app:iconGravity="textStart" app:iconPadding="0dp" app:iconTint="?colorError" app:layout_constraintStart_toStartOf="@id/banner_pp" app:layout_constraintTop_toTopOf="@id/banner_pp" app:strokeColor="?colorError" /> </androidx.appcompat.widget.LinearLayoutCompat> </com.google.android.material.card.MaterialCardView>
app/src/main/res/layouts/mastodon/layout/activity_edit_profile.xml +66 −2 Original line number Diff line number Diff line Loading @@ -161,6 +161,16 @@ app:layout_constraintTop_toBottomOf="@id/acct" tools:text="@tools:sample/lorem/random" /> <com.google.android.material.textview.MaterialTextView android:id="@+id/fields_label" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="12dp" android:layout_marginTop="12dp" android:text="@string/fields_title" android:textAppearance="@style/TextAppearance.Material3.BodyMedium" app:layout_constraintTop_toBottomOf="@id/bio" /> <androidx.appcompat.widget.LinearLayoutCompat android:id="@+id/fields" android:layout_width="match_parent" Loading @@ -168,7 +178,7 @@ android:layout_marginHorizontal="12dp" android:layout_marginTop="12dp" android:orientation="vertical" app:layout_constraintTop_toBottomOf="@id/bio"> app:layout_constraintTop_toBottomOf="@id/fields_label"> <androidx.appcompat.widget.LinearLayoutCompat android:id="@+id/fields_container" Loading @@ -188,6 +198,60 @@ </androidx.appcompat.widget.LinearLayoutCompat> <com.google.android.material.textview.MaterialTextView android:id="@+id/featured_hashtags_label" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="12dp" android:layout_marginTop="12dp" android:text="@string/featured_hashtags_title" android:textAppearance="@style/TextAppearance.Material3.BodyMedium" app:layout_constraintTop_toBottomOf="@id/fields" /> <androidx.appcompat.widget.LinearLayoutCompat android:id="@+id/featured_hashtags" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="12dp" android:layout_marginTop="12dp" android:orientation="vertical" app:layout_constraintTop_toBottomOf="@id/featured_hashtags_label"> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <com.google.android.material.textview.MaterialTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/Suggestions"/> <com.google.android.material.textview.MaterialTextView android:id="@+id/featured_hashtags_suggestions" android:layout_marginStart="10dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:text="@string/Suggestions"/> </androidx.appcompat.widget.LinearLayoutCompat> <androidx.appcompat.widget.LinearLayoutCompat android:layout_marginTop="5dp" android:id="@+id/featured_hashtags_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" /> <com.google.android.material.button.MaterialButton android:id="@+id/add_featured_hashtags" style="@style/Widget.Material3.Button.OutlinedButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" android:layout_marginVertical="6dp" android:text="@string/add_featured_hashtag" app:icon="@drawable/ic_baseline_add_24" /> </androidx.appcompat.widget.LinearLayoutCompat> <com.google.android.material.textview.MaterialTextView android:id="@+id/visibility_label" android:layout_width="match_parent" Loading @@ -196,7 +260,7 @@ android:layout_marginTop="12dp" android:text="@string/toots_visibility_title" android:textAppearance="@style/TextAppearance.Material3.BodyMedium" app:layout_constraintTop_toBottomOf="@id/fields" /> app:layout_constraintTop_toBottomOf="@id/featured_hashtags" /> <com.google.android.material.button.MaterialButtonToggleGroup android:id="@+id/visibility_group" Loading
app/src/main/res/values/strings.xml +6 −0 Original line number Diff line number Diff line Loading @@ -732,13 +732,19 @@ <string name="interactions">Interactions</string> <string name="add_filter">Add filter</string> <string name="add_field">Add Field</string> <string name="add_featured_hashtag">Add Featured Hashtag</string> <string name="no_feature_hashtag_suggestion">No suggestions for featured hashtags!</string> <string name="unlocked">Unlocked</string> <string name="locked">Locked</string> <string name="save_changes">Save changes</string> <string name="set_bot_content">Bot account</string> <string name="fields_title">Add or remove fields</string> <string name="featured_hashtags_title">Add or remove featured hashtags</string> <string name="set_discoverable_content">Account discoverable</string> <string name="delete_field">Delete field</string> <string name="delete_featured_hashtag">Delete featured hashtag</string> <string name="delete_field_confirm">Are you sure you want to delete that field?</string> <string name="delete_featured_hashtag_confirm">Are you sure you want to delete that featured hashtag?</string> <string name="profiled_updated">Profile has been updated!</string> <string name="not_valid_list_name">List name is not valid!</string> <string name="no_account_in_list">No accounts found for this list!</string> Loading