mirror of
https://github.com/MCV-Software/TWBlue.git
synced 2024-11-23 03:38:08 -06:00
Fixed merge conflicts with next-gen
This commit is contained in:
commit
c8c242a27f
@ -471,11 +471,18 @@ class BaseBuffer(base.Buffer):
|
|||||||
|
|
||||||
def onFocus(self, *args, **kwargs):
|
def onFocus(self, *args, **kwargs):
|
||||||
tweet = self.get_tweet()
|
tweet = self.get_tweet()
|
||||||
|
<<<<<<< HEAD
|
||||||
if self.session.settings["general"]["relative_times"] == True:
|
if self.session.settings["general"]["relative_times"] == True:
|
||||||
# fix this:
|
# fix this:
|
||||||
original_date = arrow.get(self.session.db[self.name][self.buffer.list.get_selected()].created_at, locale="en")
|
original_date = arrow.get(self.session.db[self.name][self.buffer.list.get_selected()].created_at, locale="en")
|
||||||
ts = original_date.humanize(locale=languageHandler.getLanguage())
|
ts = original_date.humanize(locale=languageHandler.getLanguage())
|
||||||
self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts)
|
self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts)
|
||||||
|
=======
|
||||||
|
# fix this:
|
||||||
|
original_date = arrow.get(self.session.db[self.name][self.buffer.list.get_selected()].created_at, locale="en")
|
||||||
|
ts = original_date.humanize(locale=languageHandler.getLanguage())
|
||||||
|
self.buffer.list.list.SetItem(self.buffer.list.get_selected(), 2, ts)
|
||||||
|
>>>>>>> next-gen
|
||||||
if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet):
|
if self.session.settings['sound']['indicate_audio'] and utils.is_audio(tweet):
|
||||||
self.session.sound.play("audio.ogg")
|
self.session.sound.play("audio.ogg")
|
||||||
if self.session.settings['sound']['indicate_geo'] and utils.is_geocoded(tweet):
|
if self.session.settings['sound']['indicate_geo'] and utils.is_geocoded(tweet):
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import time
|
import time
|
||||||
import platform
|
|
||||||
import wx
|
import wx
|
||||||
|
from wxUI import buffers, commonMessageDialogs, menus
|
||||||
|
from controller import user, messages
|
||||||
|
from controller import messages
|
||||||
import widgetUtils
|
import widgetUtils
|
||||||
import output
|
import output
|
||||||
import logging
|
import logging
|
||||||
|
@ -230,7 +230,7 @@ class Controller(object):
|
|||||||
self.set_systray_icon()
|
self.set_systray_icon()
|
||||||
|
|
||||||
def check_invisible_at_startup(self):
|
def check_invisible_at_startup(self):
|
||||||
# Visibility check. It does only work for windows.
|
# Visibility check.
|
||||||
if config.app["app-settings"]["hide_gui"] == True:
|
if config.app["app-settings"]["hide_gui"] == True:
|
||||||
self.show_hide()
|
self.show_hide()
|
||||||
self.view.Show()
|
self.view.Show()
|
||||||
|
@ -1,3 +1 @@
|
|||||||
from __future__ import absolute_import
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from .soundsTutorial import soundsTutorial
|
from .soundsTutorial import soundsTutorial
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from gi.repository import Gtk
|
|
||||||
import widgetUtils
|
|
||||||
|
|
||||||
class soundsTutorialDialog(Gtk.Dialog):
|
|
||||||
def __init__(self, actions):
|
|
||||||
super(soundsTutorialDialog, self).__init__("Sounds tutorial", None, 0, (Gtk.STOCK_CANCEL, widgetUtils.CANCEL))
|
|
||||||
box = self.get_content_area()
|
|
||||||
label = Gtk.Label("Press enter for listen the sound")
|
|
||||||
self.list = widgetUtils.list("Action")
|
|
||||||
self.populate_actions(actions)
|
|
||||||
lBox = Gtk.Box(spacing=6)
|
|
||||||
lBox.add(label)
|
|
||||||
lBox.add(self.list.list)
|
|
||||||
box.add(lBox)
|
|
||||||
self.play = Gtk.Button("Play")
|
|
||||||
box.add(self.play)
|
|
||||||
self.show_all()
|
|
||||||
|
|
||||||
def populate_actions(self, actions):
|
|
||||||
for i in actions:
|
|
||||||
self.list.insert_item(i)
|
|
||||||
|
|
||||||
def get_selected(self):
|
|
||||||
return self.list.get_selected()
|
|
@ -1,4 +1,3 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
#Reverse sort, by Bill Dengler <codeofdusk@gmail.com> for use in TWBlue http://twblue.es
|
#Reverse sort, by Bill Dengler <codeofdusk@gmail.com> for use in TWBlue http://twblue.es
|
||||||
def invert_tuples(t):
|
def invert_tuples(t):
|
||||||
"Invert a list of tuples, so that the 0th element becomes the -1th, and the -1th becomes the 0th."
|
"Invert a list of tuples, so that the 0th element becomes the -1th, and the -1th becomes the 0th."
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from builtins import object
|
|
||||||
import platform
|
import platform
|
||||||
import widgetUtils
|
import widgetUtils
|
||||||
import os
|
import os
|
||||||
@ -9,10 +6,7 @@ import paths
|
|||||||
import logging
|
import logging
|
||||||
log = logging.getLogger("extra.SoundsTutorial.soundsTutorial")
|
log = logging.getLogger("extra.SoundsTutorial.soundsTutorial")
|
||||||
from . import soundsTutorial_constants
|
from . import soundsTutorial_constants
|
||||||
if platform.system() == "Windows":
|
from . import wx_ui as UI
|
||||||
from . import wx_ui as UI
|
|
||||||
elif platform.system() == "Linux":
|
|
||||||
from . import gtk_ui as UI
|
|
||||||
|
|
||||||
class soundsTutorial(object):
|
class soundsTutorial(object):
|
||||||
def __init__(self, sessionObject):
|
def __init__(self, sessionObject):
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
#-*- coding: utf-8 -*-
|
#-*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
#-*- coding: utf-8 -*-
|
|
||||||
from . import reverse_sort
|
from . import reverse_sort
|
||||||
import application
|
import application
|
||||||
actions = reverse_sort.reverse_sort([ ("audio", _(u"Audio tweet.")),
|
actions = reverse_sort.reverse_sort([ ("audio", _(u"Audio tweet.")),
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
import wx
|
import wx
|
||||||
import widgetUtils
|
import widgetUtils
|
||||||
|
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import absolute_import
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from builtins import next
|
|
||||||
from builtins import object
|
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from . import wx_ui
|
from . import wx_ui
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
|
||||||
import re
|
import re
|
||||||
from enchant.tokenize import Filter
|
from enchant.tokenize import Filter
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
############################################################
|
############################################################
|
||||||
from __future__ import unicode_literals
|
|
||||||
import wx
|
import wx
|
||||||
import application
|
import application
|
||||||
|
|
||||||
|
@ -2,7 +2,4 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from . import translator
|
from . import translator
|
||||||
import platform
|
from . import wx_ui as gui
|
||||||
if platform.system() == "Windows":
|
|
||||||
from . import wx_ui as gui
|
|
||||||
|
|
Binary file not shown.
@ -1,23 +1,22 @@
|
|||||||
# SOME DESCRIPTIVE TITLE.
|
# SOME DESCRIPTIVE TITLE.
|
||||||
# Copyright (C) 2022 ORGANIZATION
|
# Copyright (C) 2022 ORGANIZATION
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2022.
|
||||||
# Riku <riku@riku22.net>, 2022.
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: manuel@manuelcortez.net\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2022-08-16 17:50-0500\n"
|
"POT-Creation-Date: 2022-08-16 17:50-0500\n"
|
||||||
"PO-Revision-Date: 2022-09-09 06:02+0000\n"
|
"PO-Revision-Date: 2022-08-20 07:18+0900\n"
|
||||||
"Last-Translator: Riku <riku@riku22.net>\n"
|
"Last-Translator: 陸 <support@riku22.net>\n"
|
||||||
"Language-Team: Japanese <https://weblate.mcvsoftware.com/projects/twblue/"
|
"Language-Team: \n"
|
||||||
"twblue/ja/>\n"
|
"Language: ja_JP\n"
|
||||||
"Language: ja\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
"X-Generator: Weblate 4.13.1\n"
|
|
||||||
"Generated-By: Babel 2.10.3\n"
|
"Generated-By: Babel 2.10.3\n"
|
||||||
|
"X-Generator: Poedit 3.1.1\n"
|
||||||
|
|
||||||
#: languageHandler.py:61
|
#: languageHandler.py:61
|
||||||
msgctxt "languageName"
|
msgctxt "languageName"
|
||||||
|
@ -7,4 +7,3 @@ Contents of this package:
|
|||||||
manager: Handles multiple sessions, setting the configuration files and check if the session is valid. Part of the model.
|
manager: Handles multiple sessions, setting the configuration files and check if the session is valid. Part of the model.
|
||||||
session: Creates a twitter session for an user. The other part of the model.
|
session: Creates a twitter session for an user. The other part of the model.
|
||||||
"""
|
"""
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
from gi.repository import Gtk
|
|
||||||
import widgetUtils
|
|
||||||
|
|
||||||
class sessionManagerWindow(widgetUtils.baseDialog):
|
|
||||||
def __init__(self):
|
|
||||||
super(sessionManagerWindow, self).__init__("Session Manager", None, 0, (Gtk.STOCK_OK, widgetUtils.OK, Gtk.STOCK_CANCEL, widgetUtils.CANCEL))
|
|
||||||
self.list = widgetUtils.list("Session")
|
|
||||||
self.box.add(self.list.list)
|
|
||||||
btnBox = Gtk.Box(spacing=6)
|
|
||||||
self.new = Gtk.Button("New account")
|
|
||||||
self.remove = Gtk.Button("Remove account")
|
|
||||||
self.configuration = Gtk.Button("Configuration")
|
|
||||||
btnBox.add(self.new)
|
|
||||||
btnBox.add(self.remove)
|
|
||||||
btnBox.add(self.configuration)
|
|
||||||
self.box.add(btnBox)
|
|
||||||
self.show_all()
|
|
||||||
|
|
||||||
def fill_list(self, sessionsList):
|
|
||||||
for i in sessionsList:
|
|
||||||
self.list.insert_item(False, i)
|
|
||||||
if self.list.get_count() > 0:
|
|
||||||
self.list.select_item(0)
|
|
||||||
|
|
||||||
def new_account_dialog(self):
|
|
||||||
dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Authorization")
|
|
||||||
dialog.format_secondary_text("The request to authorize your Twitter account will be opened in your browser. You only need to do this once. Would you like to continue?")
|
|
||||||
answer = dialog.run()
|
|
||||||
dialog.destroy()
|
|
||||||
return answer
|
|
||||||
|
|
||||||
def add_new_session_to_list(self):
|
|
||||||
total = self.list.get_count()
|
|
||||||
name = "Authorized account %d" % (total+1)
|
|
||||||
self.list.insert_item(name)
|
|
||||||
if self.list.get_count() == 1:
|
|
||||||
self.list.select_item(0)
|
|
||||||
|
|
||||||
def show_unauthorised_error(self):
|
|
||||||
dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "Invalid user token")
|
|
||||||
dialog.format_secondary_text("Your access token is invalid or the authorization has failed. Please try again.")
|
|
||||||
answer = dialog.run()
|
|
||||||
return answer
|
|
||||||
|
|
||||||
def remove_account_dialog(self):
|
|
||||||
dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Remove account")
|
|
||||||
dialog.format_secondary_text("Do you really want delete this account?")
|
|
||||||
answer = dialog.run()
|
|
||||||
return answer
|
|
||||||
|
|
||||||
def get_selected(self):
|
|
||||||
return self.list.get_selected()
|
|
||||||
|
|
||||||
def remove_session(self, sessionID):
|
|
||||||
self.list.remove_item(sessionID)
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
""" Module to perform session actions such as addition, removal or display of the global settings dialogue. """
|
""" Module to perform session actions such as addition, removal or display of the global settings dialogue. """
|
||||||
import shutil
|
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import platform
|
|
||||||
system = platform.system()
|
|
||||||
from . import utils
|
from . import utils
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
@ -17,14 +15,11 @@ chars = "abcdefghijklmnopqrstuvwxyz"
|
|||||||
|
|
||||||
def compose_tweet(tweet, db, relative_times, show_screen_names=False, session=None):
|
def compose_tweet(tweet, db, relative_times, show_screen_names=False, session=None):
|
||||||
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
|
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
|
||||||
if system == "Windows":
|
|
||||||
original_date = arrow.get(tweet.created_at, locale="en")
|
original_date = arrow.get(tweet.created_at, locale="en")
|
||||||
if relative_times == True:
|
if relative_times == True:
|
||||||
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
else:
|
else:
|
||||||
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
||||||
else:
|
|
||||||
ts = tweet.created_at
|
|
||||||
if hasattr(tweet, "message"):
|
if hasattr(tweet, "message"):
|
||||||
value = "message"
|
value = "message"
|
||||||
elif hasattr(tweet, "full_text"):
|
elif hasattr(tweet, "full_text"):
|
||||||
@ -58,7 +53,6 @@ def compose_tweet(tweet, db, relative_times, show_screen_names=False, session=No
|
|||||||
return [user+", ", text, ts+", ", source]
|
return [user+", ", text, ts+", ", source]
|
||||||
|
|
||||||
def compose_direct_message(item, db, relative_times, show_screen_names=False, session=None):
|
def compose_direct_message(item, db, relative_times, show_screen_names=False, session=None):
|
||||||
if system == "Windows":
|
|
||||||
# Let's remove the last 3 digits in the timestamp string.
|
# Let's remove the last 3 digits in the timestamp string.
|
||||||
# Twitter sends their "epoch" timestamp with 3 digits for milliseconds and arrow doesn't like it.
|
# Twitter sends their "epoch" timestamp with 3 digits for milliseconds and arrow doesn't like it.
|
||||||
original_date = arrow.get(int(item.created_timestamp))
|
original_date = arrow.get(int(item.created_timestamp))
|
||||||
@ -66,8 +60,6 @@ def compose_direct_message(item, db, relative_times, show_screen_names=False, se
|
|||||||
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
else:
|
else:
|
||||||
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
||||||
else:
|
|
||||||
ts = item.created_timestamp
|
|
||||||
text = StripChars(item.message_create["message_data"]["text"])
|
text = StripChars(item.message_create["message_data"]["text"])
|
||||||
source = "DM"
|
source = "DM"
|
||||||
sender = session.get_user(item.message_create["sender_id"])
|
sender = session.get_user(item.message_create["sender_id"])
|
||||||
@ -125,16 +117,12 @@ def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False,
|
|||||||
return quoted_tweet
|
return quoted_tweet
|
||||||
|
|
||||||
def compose_followers_list(tweet, db, relative_times=True, show_screen_names=False, session=None):
|
def compose_followers_list(tweet, db, relative_times=True, show_screen_names=False, session=None):
|
||||||
if system == "Windows":
|
|
||||||
original_date = arrow.get(tweet.created_at, locale="en")
|
original_date = arrow.get(tweet.created_at, locale="en")
|
||||||
if relative_times == True:
|
if relative_times == True:
|
||||||
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
||||||
else:
|
else:
|
||||||
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
||||||
else:
|
|
||||||
ts = tweet.created_at
|
|
||||||
if hasattr(tweet, "status"):
|
if hasattr(tweet, "status"):
|
||||||
if system == "Windows":
|
|
||||||
original_date2 = arrow.get(tweet.status.created_at, locale="en")
|
original_date2 = arrow.get(tweet.status.created_at, locale="en")
|
||||||
if relative_times:
|
if relative_times:
|
||||||
ts2 = original_date2.humanize(locale=languageHandler.curLang[:2])
|
ts2 = original_date2.humanize(locale=languageHandler.curLang[:2])
|
||||||
@ -142,8 +130,6 @@ def compose_followers_list(tweet, db, relative_times=True, show_screen_names=Fal
|
|||||||
ts2 = original_date2.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
ts2 = original_date2.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
||||||
else:
|
else:
|
||||||
ts2 = _("Unavailable")
|
ts2 = _("Unavailable")
|
||||||
else:
|
|
||||||
ts2 = _("Unavailable")
|
|
||||||
return [_(u"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined Twitter %s") % (tweet.name, tweet.screen_name, tweet.followers_count, tweet.friends_count, tweet.statuses_count, ts2, ts)]
|
return [_(u"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined Twitter %s") % (tweet.name, tweet.screen_name, tweet.followers_count, tweet.friends_count, tweet.statuses_count, ts2, ts)]
|
||||||
|
|
||||||
def compose_list(list):
|
def compose_list(list):
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
""" this package holds different modules to extract information regarding long tweets. A long tweet contains more than one tweet (such a quoted tweet), or is made via services like twishort."""
|
""" this package holds different modules to extract information regarding long tweets. A long tweet contains more than one tweet (such a quoted tweet), or is made via services like twishort."""
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
import glob
|
|
||||||
import os.path
|
|
||||||
import platform
|
|
||||||
|
|
||||||
def find_datafiles():
|
|
||||||
system = platform.system()
|
|
||||||
if system == 'Windows':
|
|
||||||
file_ext = '*.exe'
|
|
||||||
else:
|
|
||||||
file_ext = '*.sh'
|
|
||||||
path = os.path.abspath(os.path.join(__path__[0], 'bootstrappers', file_ext))
|
|
||||||
return [('', glob.glob(path))]
|
|
@ -1,7 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import application
|
import application
|
||||||
from . import update
|
from . import update
|
||||||
import platform
|
|
||||||
import logging
|
import logging
|
||||||
import output
|
import output
|
||||||
from requests.exceptions import ConnectionError
|
from requests.exceptions import ConnectionError
|
||||||
|
Loading…
Reference in New Issue
Block a user