1.6.1 b update
This commit is contained in:
@@ -69,6 +69,15 @@
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
<receiver android:name=".ui.widget.MyWidgetProvider" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/my_widget_info" />
|
||||
</receiver>
|
||||
<service android:name=".ui.widget.MyWidgetService" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.baidu.lbsapi.API_KEY"
|
||||
@@ -123,6 +132,21 @@
|
||||
<action android:name="android.net.VpnService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service android:name=".ui.widget.WidgetUpdateService" android:exported="true" android:enabled="true"/>
|
||||
|
||||
<!-- WidgetConfigureActivity -->
|
||||
<activity android:name=".ui.widget.WidgetConfigureActivity" />
|
||||
|
||||
<!-- WidgetProvider -->
|
||||
<receiver android:name=".ui.widget.MyWidgetProvider" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/my_widget_info" />
|
||||
</receiver>
|
||||
|
||||
<service android:name="org.astral.findmaimaiultra.utill.updater.server.HttpServerService"
|
||||
android:exported="true" />
|
||||
|
||||
@@ -267,8 +267,18 @@ public class HomeFragment extends Fragment {
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private void sendGetRequest() {
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
String tag = "";
|
||||
String web = "";
|
||||
try {
|
||||
tag = city.split("市")[0];
|
||||
web = "http://mai.godserver.cn:11451/api/mai/v1/search?prompt1=" + tag+ "&status=市";
|
||||
}catch ( Exception e) {
|
||||
tag = "xy("+ x +","+ y +")";
|
||||
web = "http://mai.godserver.cn:11451/api/mai/v1/search?prompt1=" + tag+ "&status=xy";
|
||||
}
|
||||
|
||||
Log.d("WebWebWebWebWebWebWebWebWebWeb ", web);
|
||||
|
||||
String web = "http://mai.godserver.cn:11451/api/mai/v1/search?prompt1=" + city.split("市")[0] + "&status=市";
|
||||
if (!isFlag) {
|
||||
web = "http://mai.godserver.cn:11451/api/mai/v1/search?data_place=" + tagplace;
|
||||
}
|
||||
@@ -348,55 +358,45 @@ public class HomeFragment extends Fragment {
|
||||
|
||||
boolean flag2 = true;
|
||||
if (flag2) {
|
||||
adapter = new PlaceAdapter(a, new PlaceAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(Place place) {
|
||||
Intent intent = new Intent(context, PageActivity.class);
|
||||
intent.putExtra("id", place.getId());
|
||||
intent.putExtra("name", place.getName());
|
||||
intent.putExtra("address", place.getAddress());
|
||||
intent.putExtra("province", place.getProvince());
|
||||
intent.putExtra("city", place.getCity());
|
||||
intent.putExtra("area", place.getArea());
|
||||
intent.putExtra("x", place.getX());
|
||||
intent.putExtra("y", place.getY());
|
||||
intent.putExtra("count", place.getCount());
|
||||
intent.putExtra("bad", place.getBad());
|
||||
intent.putExtra("good", place.getGood());
|
||||
intent.putExtra("num", place.getNum());
|
||||
intent.putExtra("numJ", place.getNumJ());
|
||||
intent.putExtra("meituan", place.getMeituan_link());
|
||||
intent.putExtra("douyin", place.getDouyin_link());
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
adapter = new PlaceAdapter(a, new PlaceAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(Place place) {
|
||||
Intent intent = new Intent(context, PageActivity.class);
|
||||
intent.putExtra("id", place.getId());
|
||||
intent.putExtra("name", place.getName());
|
||||
intent.putExtra("address", place.getAddress());
|
||||
intent.putExtra("province", place.getProvince());
|
||||
intent.putExtra("city", place.getCity());
|
||||
intent.putExtra("area", place.getArea());
|
||||
intent.putExtra("x", place.getX());
|
||||
intent.putExtra("y", place.getY());
|
||||
intent.putExtra("count", place.getCount());
|
||||
intent.putExtra("bad", place.getBad());
|
||||
intent.putExtra("good", place.getGood());
|
||||
intent.putExtra("num", place.getNum());
|
||||
intent.putExtra("numJ", place.getNumJ());
|
||||
intent.putExtra("meituan", place.getMeituan_link());
|
||||
intent.putExtra("douyin", place.getDouyin_link());
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
// 设置 Toolbar 标题
|
||||
String navHomeLabel = getString(R.string.menu_home);
|
||||
Toolbar toolbar = ((MainActivity) requireActivity()).findViewById(R.id.toolbar);
|
||||
if(!(toolbar.getTitle().equals("歌曲成绩") || toolbar.getTitle().equals("地图")|| toolbar.getTitle().equals("设置"))) {
|
||||
toolbar.setTitle("FindMaimaiDX - " + a.size() + " 店铺" + "\n" + tot);
|
||||
}
|
||||
|
||||
// 更新 SharedViewModel 中的 Map
|
||||
sharedViewModel.setPlacelist(new ArrayList<>(a));
|
||||
// 通知适配器数据已更改
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
// 设置Toolbar
|
||||
|
||||
for (Place p : a) {
|
||||
if (p.getX() == 0.0) {
|
||||
// Log.i(p.getId() + "", p.getName() + "没有坐标");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<Place> parseJsonToPlaceList(String jsonString) {
|
||||
Gson gson = new Gson();
|
||||
Type placeListType = new TypeToken<List<Place>>() {
|
||||
|
||||
@@ -311,11 +311,12 @@ public class PixivFragment extends Fragment {
|
||||
Log.d("PixivFragment111111111", "onResponse: " + res);
|
||||
if (response.isSuccessful()) {
|
||||
PagePixivResponse photoResponse = new Gson().fromJson(res, PagePixivResponse.class);
|
||||
TextView user = view.findViewById(R.id.user);
|
||||
user.setText(photoResponse.getBody().getUserName());
|
||||
TextView des = view.findViewById(R.id.des);
|
||||
des.setText(photoResponse.getBody().getDescription());
|
||||
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
TextView user = view.findViewById(R.id.user);
|
||||
user.setText(photoResponse.getBody().getUserName());
|
||||
TextView des = view.findViewById(R.id.des);
|
||||
des.setText(photoResponse.getBody().getDescription());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,9 +408,11 @@ public class PixivFragment extends Fragment {
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
|
||||
if (bitmap != null) {
|
||||
handler.post(() -> {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
li.addView(imageView);
|
||||
snackbar.dismiss();
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
li.addView(imageView);
|
||||
snackbar.dismiss();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
handler.post(() -> {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.astral.findmaimaiultra.ui.widget;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.widget.RemoteViews;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.astral.findmaimaiultra.ui.MainActivity;
|
||||
|
||||
public class MyWidgetProvider extends AppWidgetProvider {
|
||||
private static final String ACTION_UPDATE = "org.astral.findmaimaiultra.ui.widget.UPDATE_WIDGET";
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_2x2);
|
||||
|
||||
// 设置点击事件
|
||||
Intent clickIntent = new Intent(context, MyWidgetProvider.class);
|
||||
clickIntent.setAction(ACTION_UPDATE);
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
views.setOnClickPendingIntent(R.id.widget_container, pendingIntent);
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
if (ACTION_UPDATE.equals(intent.getAction())) {
|
||||
// 启动 WidgetUpdateService
|
||||
Intent serviceIntent = new Intent(context, WidgetUpdateService.class);
|
||||
context.startService(serviceIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.astral.findmaimaiultra.ui.widget;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.RemoteViewsService;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MyWidgetService extends RemoteViewsService {
|
||||
@Override
|
||||
public RemoteViewsFactory onGetViewFactory(Intent intent) {
|
||||
return new MyWidgetFactory(this.getApplicationContext(), intent);
|
||||
}
|
||||
}
|
||||
|
||||
class MyWidgetFactory implements RemoteViewsService.RemoteViewsFactory {
|
||||
private Context context;
|
||||
private List<String> dataList;
|
||||
|
||||
public MyWidgetFactory(Context context, Intent intent) {
|
||||
this.context = context;
|
||||
this.dataList = intent.getStringArrayListExtra("dataList");
|
||||
if (dataList == null) {
|
||||
dataList = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
// 初始化数据
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataSetChanged() {
|
||||
// 数据集发生变化时调用
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
// 清理资源
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return dataList.size();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RemoteViews getViewAt(int position) {
|
||||
@SuppressLint("RemoteViewLayout") RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_item);
|
||||
views.setTextViewText(R.id.widget_item_text, dataList.get(position));
|
||||
return views;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteViews getLoadingView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.astral.findmaimaiultra.ui.widget;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
|
||||
public class WidgetConfigureActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_widget_configure);
|
||||
// 添加配置逻辑
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package org.astral.findmaimaiultra.ui.widget;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import android.widget.RemoteViews;
|
||||
import androidx.annotation.Nullable;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.astral.findmaimaiultra.R;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WidgetUpdateService extends IntentService {
|
||||
private static final String TAG = "WidgetUpdateService";
|
||||
|
||||
public WidgetUpdateService() {
|
||||
super("WidgetUpdateService");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(@Nullable Intent intent) {
|
||||
if (intent != null) {
|
||||
fetchDataAndUpdateWidget();
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchDataAndUpdateWidget() {
|
||||
Log.d(TAG + "loading", "Fetching data and updating widget");
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
String url = "http://yourserver.com/api/data"; // 替换为实际的API地址
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
Log.e(TAG, "Error fetching data: " + e.getMessage());
|
||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(WidgetUpdateService.this);
|
||||
ComponentName thisWidget = new ComponentName(WidgetUpdateService.this, MyWidgetProvider.class);
|
||||
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
RemoteViews views = new RemoteViews(getPackageName(), R.layout.widget_2x2);
|
||||
|
||||
// 将数据列表转换为字符串
|
||||
StringBuilder dataText = new StringBuilder();
|
||||
dataText.append("加载失败");
|
||||
// 设置TextView的文本内容
|
||||
views.setTextViewText(R.id.widget_text, dataText.toString());
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
String responseData = response.body().string();
|
||||
List<String> dataList = parseData(responseData);
|
||||
|
||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(WidgetUpdateService.this);
|
||||
ComponentName thisWidget = new ComponentName(WidgetUpdateService.this, MyWidgetProvider.class);
|
||||
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
|
||||
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
RemoteViews views = new RemoteViews(getPackageName(), R.layout.widget_2x2);
|
||||
|
||||
// 将数据列表转换为字符串
|
||||
StringBuilder dataText = new StringBuilder();
|
||||
for (String data : dataList) {
|
||||
dataText.append(data).append("\n");
|
||||
}
|
||||
|
||||
// 设置TextView的文本内容
|
||||
views.setTextViewText(R.id.widget_text, dataText.toString());
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Failed to fetch data: " + response.code());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<String> parseData(String jsonData) {
|
||||
List<String> dataList = new ArrayList<>();
|
||||
try {
|
||||
JSONArray jsonArray = new JSONArray(jsonData);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
||||
String data = jsonObject.getString("data_key"); // 替换为实际的JSON键
|
||||
dataList.add(data);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error parsing JSON: " + e.getMessage());
|
||||
}
|
||||
return dataList;
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,7 @@ public class AddressParser {
|
||||
HomeFragment.province = "天津市";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}catch (Exception e) {
|
||||
}
|
||||
|
||||
14
app/src/main/res/drawable/rounded_background.xml
Normal file
14
app/src/main/res/drawable/rounded_background.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<!-- res/drawable/rounded_background.xml -->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/white"/>
|
||||
<corners android:radius="16dp"/>
|
||||
<padding
|
||||
android:left="8dp"
|
||||
android:top="8dp"
|
||||
android:right="8dp"
|
||||
android:bottom="8dp"/>
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#DDDDDD"/>
|
||||
</shape>
|
||||
@@ -137,25 +137,27 @@
|
||||
android:text="Re:Mas"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal">
|
||||
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp"
|
||||
|
||||
android:orientation="vertical">
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="saveText"
|
||||
android:text="Save" />
|
||||
android:text="Save"/>
|
||||
<Button
|
||||
android:id="@+id/button2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="saveText"
|
||||
android:text="注册水鱼账号" />
|
||||
android:text="注册水鱼账号"/>
|
||||
<Button
|
||||
android:id="@+id/sy2lx"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="saveText"
|
||||
android:text="水鱼数据迁移到落雪" />
|
||||
android:text="水鱼数据迁移到落雪"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
|
||||
16
app/src/main/res/layout/activity_widget_configure.xml
Normal file
16
app/src/main/res/layout/activity_widget_configure.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Configure Widget"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<!-- 添加其他配置控件 -->
|
||||
</LinearLayout>
|
||||
17
app/src/main/res/layout/widget_2x2.xml
Normal file
17
app/src/main/res/layout/widget_2x2.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/widget_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:background="@android:color/white">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/widget_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@android:color/black"
|
||||
android:padding="16dp" />
|
||||
</LinearLayout>
|
||||
14
app/src/main/res/layout/widget_item.xml
Normal file
14
app/src/main/res/layout/widget_item.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/widget_item_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@android:color/black" />
|
||||
</LinearLayout>
|
||||
14
app/src/main/res/xml/my_widget_info.xml
Normal file
14
app/src/main/res/xml/my_widget_info.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="140dp"
|
||||
android:minHeight="140dp"
|
||||
android:updatePeriodMillis="3600000"
|
||||
android:initialLayout="@layout/widget_2x2"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:widgetCategory="home_screen"
|
||||
android:previewImage="@drawable/rounded_background"
|
||||
android:configure="org.astral.findmaimaiultra.ui.widget.WidgetConfigureActivity">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
</appwidget-provider>
|
||||
Reference in New Issue
Block a user