Share+Delete Button
This commit is contained in:
parent
1d983b9ac0
commit
d6dcf28d89
4
android/.idea/assetWizardSettings.xml
generated
4
android/.idea/assetWizardSettings.xml
generated
@ -67,8 +67,8 @@
|
|||||||
<option name="values">
|
<option name="values">
|
||||||
<map>
|
<map>
|
||||||
<entry key="assetSourceType" value="FILE" />
|
<entry key="assetSourceType" value="FILE" />
|
||||||
<entry key="outputName" value="ic_garbage" />
|
<entry key="outputName" value="ic_share" />
|
||||||
<entry key="sourceFile" value="C:\Users\Mike\Downloads\garbage.svg" />
|
<entry key="sourceFile" value="C:\Users\Mike\Downloads\baseline-share-24px.svg" />
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
</PersistentState>
|
</PersistentState>
|
||||||
|
@ -100,7 +100,5 @@ public class SCNApp extends Application implements LifecycleObserver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Share button on expand
|
|
||||||
//TODO: Delete button on expand
|
|
||||||
//TODO: Config for collapsed line count
|
//TODO: Config for collapsed line count
|
||||||
//TODO: Sometimes ads but promode
|
//TODO: Sometimes ads but promode
|
||||||
|
@ -52,7 +52,7 @@ public class SCNSettings
|
|||||||
|
|
||||||
public boolean Enabled = true;
|
public boolean Enabled = true;
|
||||||
public int LocalCacheSize = 500;
|
public int LocalCacheSize = 500;
|
||||||
public boolean EnableDeleteSwipe = true;
|
public boolean EnableDeleteSwipe = false;
|
||||||
|
|
||||||
public final NotificationSettings PriorityLow = new NotificationSettings(PriorityEnum.LOW);
|
public final NotificationSettings PriorityLow = new NotificationSettings(PriorityEnum.LOW);
|
||||||
public final NotificationSettings PriorityNorm = new NotificationSettings(PriorityEnum.NORMAL);
|
public final NotificationSettings PriorityNorm = new NotificationSettings(PriorityEnum.NORMAL);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.blackforestbytes.simplecloudnotifier.view;
|
package com.blackforestbytes.simplecloudnotifier.view;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -9,8 +10,10 @@ import android.widget.RelativeLayout;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.blackforestbytes.simplecloudnotifier.R;
|
import com.blackforestbytes.simplecloudnotifier.R;
|
||||||
|
import com.blackforestbytes.simplecloudnotifier.SCNApp;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.CMessage;
|
import com.blackforestbytes.simplecloudnotifier.model.CMessage;
|
||||||
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
|
||||||
|
import com.google.android.material.button.MaterialButton;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -53,7 +56,7 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
{
|
{
|
||||||
CMessage msg = CMessageList.inst().tryGetFromBack(position);
|
CMessage msg = CMessageList.inst().tryGetFromBack(position);
|
||||||
MessagePresenter view = (MessagePresenter) holder;
|
MessagePresenter view = (MessagePresenter) holder;
|
||||||
view.setMessage(msg);
|
view.setMessage(msg, position);
|
||||||
|
|
||||||
viewHolders.put(view, true);
|
viewHolders.put(view, true);
|
||||||
}
|
}
|
||||||
@ -110,7 +113,11 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
public RelativeLayout viewForeground;
|
public RelativeLayout viewForeground;
|
||||||
public RelativeLayout viewBackground;
|
public RelativeLayout viewBackground;
|
||||||
|
|
||||||
|
public MaterialButton btnShare;
|
||||||
|
public MaterialButton btnDelete;
|
||||||
|
|
||||||
private CMessage data;
|
private CMessage data;
|
||||||
|
private int datapos;
|
||||||
|
|
||||||
MessagePresenter(View itemView)
|
MessagePresenter(View itemView)
|
||||||
{
|
{
|
||||||
@ -121,6 +128,8 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
ivPriority = itemView.findViewById(R.id.ivPriority);
|
ivPriority = itemView.findViewById(R.id.ivPriority);
|
||||||
viewForeground = itemView.findViewById(R.id.layoutFront);
|
viewForeground = itemView.findViewById(R.id.layoutFront);
|
||||||
viewBackground = itemView.findViewById(R.id.layoutBack);
|
viewBackground = itemView.findViewById(R.id.layoutBack);
|
||||||
|
btnShare = itemView.findViewById(R.id.btnShare);
|
||||||
|
btnDelete = itemView.findViewById(R.id.btnDelete);
|
||||||
|
|
||||||
itemView.setOnClickListener(this);
|
itemView.setOnClickListener(this);
|
||||||
tvTimestamp.setOnClickListener(this);
|
tvTimestamp.setOnClickListener(this);
|
||||||
@ -128,16 +137,27 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
tvMessage.setOnClickListener(this);
|
tvMessage.setOnClickListener(this);
|
||||||
ivPriority.setOnClickListener(this);
|
ivPriority.setOnClickListener(this);
|
||||||
viewForeground.setOnClickListener(this);
|
viewForeground.setOnClickListener(this);
|
||||||
|
|
||||||
|
btnShare.setOnClickListener(v ->
|
||||||
|
{
|
||||||
|
if (data == null) return;
|
||||||
|
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
|
||||||
|
sharingIntent.setType("text/plain");
|
||||||
|
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, data.Title);
|
||||||
|
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, data.Content);
|
||||||
|
SCNApp.getMainActivity().startActivity(Intent.createChooser(sharingIntent, "Share message"));
|
||||||
|
|
||||||
|
});
|
||||||
|
btnDelete.setOnClickListener(v -> { if (data != null) SCNApp.getMainActivity().adpTabs.tab1.deleteMessage(datapos); });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMessage(CMessage msg)
|
void setMessage(CMessage msg, int pos)
|
||||||
{
|
{
|
||||||
tvTimestamp.setText(msg.formatTimestamp());
|
tvTimestamp.setText(msg.formatTimestamp());
|
||||||
tvTitle.setText(msg.Title);
|
tvTitle.setText(msg.Title);
|
||||||
tvMessage.setText(msg.Content);
|
tvMessage.setText(msg.Content);
|
||||||
|
|
||||||
tvMessage.setMaxLines(msg.IsExpandedInAdapter ? 999 : 6);
|
|
||||||
|
|
||||||
switch (msg.Priority)
|
switch (msg.Priority)
|
||||||
{
|
{
|
||||||
case LOW:
|
case LOW:
|
||||||
@ -157,6 +177,28 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
data = msg;
|
data = msg;
|
||||||
|
datapos = pos;
|
||||||
|
|
||||||
|
if (msg.IsExpandedInAdapter) expand(true); else collapse(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expand(boolean force)
|
||||||
|
{
|
||||||
|
if (data != null && data.IsExpandedInAdapter && !force) return;
|
||||||
|
if (data != null) data.IsExpandedInAdapter = true;
|
||||||
|
if (tvMessage != null) tvMessage.setMaxLines(999);
|
||||||
|
if (btnDelete != null) btnDelete.setVisibility(View.VISIBLE);
|
||||||
|
if (btnShare != null) btnShare.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collapse(boolean force)
|
||||||
|
{
|
||||||
|
if (data != null && !data.IsExpandedInAdapter && !force) return;
|
||||||
|
if (data != null) data.IsExpandedInAdapter = false;
|
||||||
|
if (tvMessage != null) tvMessage.setMaxLines(6);
|
||||||
|
if (btnDelete != null) btnDelete.setVisibility(View.GONE);
|
||||||
|
if (btnShare != null) btnShare.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -164,8 +206,7 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
{
|
{
|
||||||
if (data.IsExpandedInAdapter)
|
if (data.IsExpandedInAdapter)
|
||||||
{
|
{
|
||||||
data.IsExpandedInAdapter=false;
|
collapse(false);
|
||||||
tvMessage.setMaxLines(6);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,15 +214,10 @@ public class MessageAdapter extends RecyclerView.Adapter
|
|||||||
{
|
{
|
||||||
if (holder == null) continue;
|
if (holder == null) continue;
|
||||||
if (holder == this) continue;
|
if (holder == this) continue;
|
||||||
if (holder.tvMessage == null) continue;
|
holder.collapse(false);
|
||||||
if (!holder.data.IsExpandedInAdapter) continue;
|
|
||||||
|
|
||||||
holder.data.IsExpandedInAdapter=false;
|
|
||||||
holder.tvMessage.setMaxLines(6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.IsExpandedInAdapter=true;
|
expand(false);
|
||||||
tvMessage.setMaxLines(9999);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,18 +66,23 @@ public class NotificationsFragment extends Fragment implements MessageAdapterTou
|
|||||||
{
|
{
|
||||||
if (viewHolder instanceof MessageAdapter.MessagePresenter)
|
if (viewHolder instanceof MessageAdapter.MessagePresenter)
|
||||||
{
|
{
|
||||||
final int deletedIndex = viewHolder.getAdapterPosition();
|
deleteMessage(viewHolder.getAdapterPosition());
|
||||||
|
|
||||||
final CMessage deletedItem = adpMessages.removeItem(viewHolder.getAdapterPosition());
|
|
||||||
String name = deletedItem.Title;
|
|
||||||
|
|
||||||
Snackbar snackbar = Snackbar.make(SCNApp.getMainActivity().layoutRoot, name + " removed", Snackbar.LENGTH_LONG);
|
|
||||||
snackbar.setAction("UNDO", view -> adpMessages.restoreItem(deletedItem, deletedIndex));
|
|
||||||
snackbar.setActionTextColor(Color.YELLOW);
|
|
||||||
snackbar.show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteMessage(int pos)
|
||||||
|
{
|
||||||
|
final int deletedIndex = pos;
|
||||||
|
|
||||||
|
final CMessage deletedItem = adpMessages.removeItem(pos);
|
||||||
|
String name = deletedItem.Title;
|
||||||
|
|
||||||
|
Snackbar snackbar = Snackbar.make(SCNApp.getMainActivity().layoutRoot, name + " removed", Snackbar.LENGTH_LONG);
|
||||||
|
snackbar.setAction("UNDO", view -> adpMessages.restoreItem(deletedItem, deletedIndex));
|
||||||
|
snackbar.setActionTextColor(Color.YELLOW);
|
||||||
|
snackbar.show();
|
||||||
|
}
|
||||||
|
|
||||||
public void updateDeleteSwipeEnabled()
|
public void updateDeleteSwipeEnabled()
|
||||||
{
|
{
|
||||||
if (touchHelper != null) touchHelper.updateEnabled();
|
if (touchHelper != null) touchHelper.updateEnabled();
|
||||||
|
10
android/app/src/main/res/drawable/ic_share_small.xml
Normal file
10
android/app/src/main/res/drawable/ic_share_small.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="12sp"
|
||||||
|
android:height="12sp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
|
||||||
|
</vector>
|
16
android/app/src/main/res/drawable/ic_trash_small.xml
Normal file
16
android/app/src/main/res/drawable/ic_trash_small.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<vector
|
||||||
|
android:height="12sp"
|
||||||
|
android:width="12sp"
|
||||||
|
android:viewportHeight="53"
|
||||||
|
android:viewportWidth="53"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M42.943,6H33.5V3c0,-1.654 -1.346,-3 -3,-3h-8c-1.654,0 -3,1.346 -3,3v3h-9.443C8.096,6 6.5,7.596 6.5,9.557V14h2h36h2V9.557C46.5,7.596 44.904,6 42.943,6zM31.5,6h-10V3c0,-0.552 0.449,-1 1,-1h8c0.551,0 1,0.448 1,1V6z"/>
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M8.5,49.271C8.5,51.327 10.173,53 12.229,53h28.541c2.057,0 3.729,-1.673 3.729,-3.729V16h-36V49.271z"/>
|
||||||
|
|
||||||
|
</vector>
|
@ -12,8 +12,7 @@
|
|||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:background="?attr/colorPrimary"
|
android:background="?attr/colorPrimary"
|
||||||
android:elevation="6dp"
|
android:elevation="6dp"
|
||||||
android:minHeight="?attr/actionBarSize"
|
android:minHeight="?attr/actionBarSize" />
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
|
|
||||||
|
|
||||||
<com.google.android.material.tabs.TabLayout
|
<com.google.android.material.tabs.TabLayout
|
||||||
android:id="@+id/tab_layout"
|
android:id="@+id/tab_layout"
|
||||||
@ -22,8 +21,7 @@
|
|||||||
android:layout_below="@+id/toolbar"
|
android:layout_below="@+id/toolbar"
|
||||||
android:background="?attr/colorPrimary"
|
android:background="?attr/colorPrimary"
|
||||||
android:elevation="6dp"
|
android:elevation="6dp"
|
||||||
android:minHeight="?attr/actionBarSize"
|
android:minHeight="?attr/actionBarSize" />
|
||||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager.widget.ViewPager
|
||||||
android:id="@+id/pager"
|
android:id="@+id/pager"
|
||||||
|
@ -198,19 +198,27 @@
|
|||||||
app:layout_constraintBottom_toTopOf="@+id/btnAccountReset"
|
app:layout_constraintBottom_toTopOf="@+id/btnAccountReset"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/ic_img_quota" />
|
app:layout_constraintTop_toBottomOf="@+id/ic_img_quota" />
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/btnAccountReset"
|
android:id="@+id/btnAccountReset"
|
||||||
|
app:cornerRadius="0dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:backgroundTint="#fa315b"
|
||||||
android:text="@string/str_reset_account"
|
android:text="@string/str_reset_account"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/btnClearLocalStorage" />
|
app:layout_constraintBottom_toTopOf="@+id/btnClearLocalStorage" />
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/btnClearLocalStorage"
|
android:id="@+id/btnClearLocalStorage"
|
||||||
|
app:cornerRadius="0dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Clear Messages"
|
android:text="Clear Messages"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:backgroundTint="#607D8B"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
@ -111,8 +111,10 @@
|
|||||||
android:gravity="center|center"
|
android:gravity="center|center"
|
||||||
android:minHeight="48dp">
|
android:minHeight="48dp">
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/prefUpgradeAccount"
|
android:id="@+id/prefUpgradeAccount"
|
||||||
|
app:cornerRadius="0dp"
|
||||||
|
android:backgroundTint="#4CAF50"
|
||||||
android:text="@string/str_upgrade_account"
|
android:text="@string/str_upgrade_account"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
@ -108,6 +108,43 @@
|
|||||||
android:paddingTop="3dp"
|
android:paddingTop="3dp"
|
||||||
android:contentDescription="@string/desc_priority_icon" />
|
android:contentDescription="@string/desc_priority_icon" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnShare"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.Icon"
|
||||||
|
app:cornerRadius="0dp"
|
||||||
|
app:icon="@drawable/ic_share_small"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="25dp"
|
||||||
|
android:layout_marginEnd="8sp"
|
||||||
|
android:insetTop="0dp"
|
||||||
|
android:insetBottom="0dp"
|
||||||
|
android:insetLeft="0dp"
|
||||||
|
android:insetRight="0dp"
|
||||||
|
android:textSize="12sp"
|
||||||
|
card_view:layout_constraintTop_toBottomOf="@id/tvMessage"
|
||||||
|
app:layout_constraintRight_toLeftOf="@id/btnDelete"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:backgroundTint="#03A9F4"
|
||||||
|
android:text="Share" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnDelete"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.Icon"
|
||||||
|
app:cornerRadius="0dp"
|
||||||
|
app:icon="@drawable/ic_trash_small"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="25dp"
|
||||||
|
android:insetTop="0dp"
|
||||||
|
android:insetBottom="0dp"
|
||||||
|
android:insetLeft="0dp"
|
||||||
|
android:insetRight="0dp"
|
||||||
|
android:textSize="12sp"
|
||||||
|
card_view:layout_constraintTop_toBottomOf="@id/tvMessage"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:backgroundTint="#F44336"
|
||||||
|
android:text="Delete"/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||||
<!-- your app branding color for the app bar -->
|
<!-- your app branding color for the app bar -->
|
||||||
<item name="colorPrimary">#3F51B5</item>
|
<item name="colorPrimary">#3F51B5</item>
|
||||||
<!-- darker variant for the status bar and contextual app bars -->
|
<!-- darker variant for the status bar and contextual app bars -->
|
||||||
<item name="colorPrimaryDark">#303F9F</item>
|
<item name="colorPrimaryDark">#303F9F</item>
|
||||||
<!-- theme UI controls like checkboxes and text fields -->
|
<!-- theme UI controls like checkboxes and text fields -->
|
||||||
<item name="colorAccent">#FF4081</item>
|
<item name="colorAccent">#FF5722</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||||
|
Loading…
Reference in New Issue
Block a user