mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
feat(scrapbook): 群贤毕至添加头像
This commit is contained in:
@@ -77,16 +77,19 @@ async def debug_render(
|
|||||||
content="代码写得好,下班走得早。",
|
content="代码写得好,下班走得早。",
|
||||||
sender="张三",
|
sender="张三",
|
||||||
reason="深刻揭示了程序员的生存法则",
|
reason="深刻揭示了程序员的生存法则",
|
||||||
|
qq=123456789,
|
||||||
),
|
),
|
||||||
GoldenQuote(
|
GoldenQuote(
|
||||||
content="这个Bug我不修,它就是个Feature。",
|
content="这个Bug我不修,它就是个Feature。",
|
||||||
sender="李四",
|
sender="李四",
|
||||||
reason="经典的开发辩解",
|
reason="经典的开发辩解",
|
||||||
|
qq=987654321,
|
||||||
),
|
),
|
||||||
GoldenQuote(
|
GoldenQuote(
|
||||||
content="PHP是世界上最好的语言!",
|
content="PHP是世界上最好的语言!",
|
||||||
sender="王五",
|
sender="王五",
|
||||||
reason="引发了长达3小时的群聊大讨论",
|
reason="引发了长达3小时的群聊大讨论",
|
||||||
|
qq=112233445,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
emoji_count=156,
|
emoji_count=156,
|
||||||
|
|||||||
@@ -152,7 +152,12 @@ class GoldenQuoteAnalyzer(BaseAnalyzer):
|
|||||||
("http", "www", "/")
|
("http", "www", "/")
|
||||||
):
|
):
|
||||||
interesting_messages.append(
|
interesting_messages.append(
|
||||||
{"sender": nickname, "time": msg_time, "content": text}
|
{
|
||||||
|
"sender": nickname,
|
||||||
|
"time": msg_time,
|
||||||
|
"content": text,
|
||||||
|
"qq": sender.get("user_id", 0),
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return interesting_messages
|
return interesting_messages
|
||||||
@@ -183,7 +188,22 @@ class GoldenQuoteAnalyzer(BaseAnalyzer):
|
|||||||
return [], TokenUsage()
|
return [], TokenUsage()
|
||||||
|
|
||||||
logger.info(f"开始从 {len(interesting_messages)} 条圣经消息中提取金句")
|
logger.info(f"开始从 {len(interesting_messages)} 条圣经消息中提取金句")
|
||||||
return await self.analyze(interesting_messages, umo)
|
logger.info(f"开始从 {len(interesting_messages)} 条圣经消息中提取金句")
|
||||||
|
quotes, usage = await self.analyze(interesting_messages, umo)
|
||||||
|
|
||||||
|
# 回填QQ号
|
||||||
|
for quote in quotes:
|
||||||
|
for msg in interesting_messages:
|
||||||
|
# 尝试匹配内容和发送者
|
||||||
|
# 注意:LLM 可能会微调内容,这里使用包含匹配或精确匹配
|
||||||
|
if (
|
||||||
|
quote.content in msg["content"]
|
||||||
|
or msg["content"] in quote.content
|
||||||
|
) and quote.sender == msg["sender"]:
|
||||||
|
quote.qq = msg.get("qq", 0)
|
||||||
|
break
|
||||||
|
|
||||||
|
return quotes, usage
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"金句分析失败: {e}")
|
logger.error(f"金句分析失败: {e}")
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class GoldenQuote:
|
|||||||
content: str
|
content: str
|
||||||
sender: str
|
sender: str
|
||||||
reason: str
|
reason: str
|
||||||
|
qq: int = 0
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -214,11 +214,15 @@ class ReportGenerator:
|
|||||||
max_golden_quotes = self.config_manager.get_max_golden_quotes()
|
max_golden_quotes = self.config_manager.get_max_golden_quotes()
|
||||||
quotes_list = []
|
quotes_list = []
|
||||||
for quote in stats.golden_quotes[:max_golden_quotes]:
|
for quote in stats.golden_quotes[:max_golden_quotes]:
|
||||||
|
avatar_url = (
|
||||||
|
await self._get_user_avatar(str(quote.qq)) if quote.qq else None
|
||||||
|
)
|
||||||
quotes_list.append(
|
quotes_list.append(
|
||||||
{
|
{
|
||||||
"content": quote.content,
|
"content": quote.content,
|
||||||
"sender": quote.sender,
|
"sender": quote.sender,
|
||||||
"reason": quote.reason,
|
"reason": quote.reason,
|
||||||
|
"avatar_url": avatar_url,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -603,10 +603,110 @@
|
|||||||
.quote-wrapper {
|
.quote-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: 85%;
|
width: 100%;
|
||||||
|
/* Occupy full width to allow internal flex to handle sizing */
|
||||||
|
max-width: 90%;
|
||||||
|
/* Limit max width */
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.q-flex-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-user-col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 70px;
|
||||||
|
/* Slightly narrower */
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-avatar-box {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-avatar {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 3px solid #fff;
|
||||||
|
background: #fff;
|
||||||
|
object-fit: cover;
|
||||||
|
/* Default base shadow */
|
||||||
|
box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Left/Odd: Blue Shadow */
|
||||||
|
.quote-wrapper:nth-child(odd) .q-avatar {
|
||||||
|
box-shadow: 0 0 0 2px var(--color-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right/Even: Orange Shadow */
|
||||||
|
.quote-wrapper:nth-child(even) .q-avatar {
|
||||||
|
box-shadow: 0 0 0 2px var(--accent-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-content-col {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
|
align-items: flex-start;
|
||||||
|
/* Default align left */
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-sender-name {
|
||||||
|
font-family: var(--font-hand);
|
||||||
|
font-size: 1.25rem;
|
||||||
|
/* Larger size for cursive font */
|
||||||
|
color: var(--ink-primary);
|
||||||
|
margin-bottom: 2px;
|
||||||
|
/* Reduce margin as underline takes space */
|
||||||
|
margin-left: 10px;
|
||||||
|
line-height: 1.2;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Underline Element */
|
||||||
|
.q-sender-name::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 4px;
|
||||||
|
background: var(--color-blue);
|
||||||
|
opacity: 0.4;
|
||||||
|
/* Marker pen feel */
|
||||||
|
border-radius: 2px;
|
||||||
|
margin-top: -6px;
|
||||||
|
/* Overlap with text bottom */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right-aligned layout for even items */
|
||||||
|
.quote-wrapper:nth-child(even) .q-flex-container {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote-wrapper:nth-child(even) .q-content-col {
|
||||||
|
align-items: flex-end;
|
||||||
|
/* Align right */
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote-wrapper:nth-child(even) .q-sender-name {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 15px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote-wrapper:nth-child(even) .q-sender-name::after {
|
||||||
|
background: var(--accent-orange);
|
||||||
|
}
|
||||||
|
|
||||||
.quote-wrapper:nth-child(odd) {
|
.quote-wrapper:nth-child(odd) {
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
@@ -619,62 +719,59 @@
|
|||||||
.q-bubble {
|
.q-bubble {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 2px solid var(--ink-primary);
|
border: 2px solid var(--ink-primary);
|
||||||
padding: 20px 25px;
|
padding: 15px 25px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
box-shadow: 5px 5px 0 var(--color-blue);
|
box-shadow: 4px 4px 0 var(--color-blue);
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
width: fit-content;
|
||||||
|
/* Dynamic width */
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote-wrapper:nth-child(odd) .q-bubble {
|
.quote-wrapper:nth-child(odd) .q-bubble {
|
||||||
border-bottom-left-radius: 0;
|
border-top-left-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote-wrapper:nth-child(even) .q-bubble {
|
.quote-wrapper:nth-child(even) .q-bubble {
|
||||||
border-bottom-right-radius: 0;
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 20px;
|
||||||
|
/* Reset bottom right */
|
||||||
background: var(--color-yellow);
|
background: var(--color-yellow);
|
||||||
box-shadow: -5px 5px 0 var(--color-pink);
|
box-shadow: -4px 4px 0 var(--color-pink);
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
border-bottom-left-radius: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-content {
|
.q-content {
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-quote-mark {
|
.q-quote-mark {
|
||||||
position: absolute;
|
display: none;
|
||||||
font-family: serif;
|
/* Hide quote mark for cleaner chat look */
|
||||||
font-size: 4rem;
|
|
||||||
color: rgba(0, 0, 0, 0.05);
|
|
||||||
top: -20px;
|
|
||||||
left: -10px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.q-author {
|
|
||||||
font-family: var(--font-hand);
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--ink-secondary);
|
|
||||||
font-size: 0.95rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-analysis-note {
|
.q-analysis-note {
|
||||||
background: #fffde7;
|
background: #fffde7;
|
||||||
padding: 12px 15px;
|
padding: 10px 15px;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
width: 95%;
|
width: fit-content;
|
||||||
margin-top: -8px;
|
/* Fit content */
|
||||||
|
max-width: 100%;
|
||||||
|
margin-top: -5px;
|
||||||
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
|
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
font-family: var(--font-body);
|
font-family: var(--font-body);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
border-radius: 0 0 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote-wrapper:nth-child(odd) .q-analysis-note {
|
.quote-wrapper:nth-child(odd) .q-analysis-note {
|
||||||
|
|||||||
@@ -603,10 +603,110 @@
|
|||||||
.quote-wrapper {
|
.quote-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: 85%;
|
width: 100%;
|
||||||
|
/* Occupy full width to allow internal flex to handle sizing */
|
||||||
|
max-width: 90%;
|
||||||
|
/* Limit max width */
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.q-flex-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 15px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-user-col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 70px;
|
||||||
|
/* Slightly narrower */
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-avatar-box {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-avatar {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 3px solid #fff;
|
||||||
|
background: #fff;
|
||||||
|
object-fit: cover;
|
||||||
|
/* Default base shadow */
|
||||||
|
box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Left/Odd: Blue Shadow */
|
||||||
|
.quote-wrapper:nth-child(odd) .q-avatar {
|
||||||
|
box-shadow: 0 0 0 2px var(--color-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right/Even: Orange Shadow */
|
||||||
|
.quote-wrapper:nth-child(even) .q-avatar {
|
||||||
|
box-shadow: 0 0 0 2px var(--accent-orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-content-col {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
|
align-items: flex-start;
|
||||||
|
/* Default align left */
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-sender-name {
|
||||||
|
font-family: 'Long Cang', cursive;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
/* Larger size for cursive font */
|
||||||
|
color: var(--ink-primary);
|
||||||
|
margin-bottom: 2px;
|
||||||
|
/* Reduce margin as underline takes space */
|
||||||
|
margin-left: 10px;
|
||||||
|
line-height: 1.2;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Underline Element */
|
||||||
|
.q-sender-name::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 4px;
|
||||||
|
background: var(--color-blue);
|
||||||
|
opacity: 0.4;
|
||||||
|
/* Marker pen feel */
|
||||||
|
border-radius: 2px;
|
||||||
|
margin-top: -6px;
|
||||||
|
/* Overlap with text bottom */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Right-aligned layout for even items */
|
||||||
|
.quote-wrapper:nth-child(even) .q-flex-container {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote-wrapper:nth-child(even) .q-content-col {
|
||||||
|
align-items: flex-end;
|
||||||
|
/* Align right */
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote-wrapper:nth-child(even) .q-sender-name {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 15px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote-wrapper:nth-child(even) .q-sender-name::after {
|
||||||
|
background: var(--accent-orange);
|
||||||
|
}
|
||||||
|
|
||||||
.quote-wrapper:nth-child(odd) {
|
.quote-wrapper:nth-child(odd) {
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
@@ -619,62 +719,59 @@
|
|||||||
.q-bubble {
|
.q-bubble {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 2px solid var(--ink-primary);
|
border: 2px solid var(--ink-primary);
|
||||||
padding: 20px 25px;
|
padding: 15px 25px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
box-shadow: 5px 5px 0 var(--color-blue);
|
box-shadow: 4px 4px 0 var(--color-blue);
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
width: fit-content;
|
||||||
|
/* Dynamic width */
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote-wrapper:nth-child(odd) .q-bubble {
|
.quote-wrapper:nth-child(odd) .q-bubble {
|
||||||
border-bottom-left-radius: 0;
|
border-top-left-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote-wrapper:nth-child(even) .q-bubble {
|
.quote-wrapper:nth-child(even) .q-bubble {
|
||||||
border-bottom-right-radius: 0;
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-right-radius: 20px;
|
||||||
|
/* Reset bottom right */
|
||||||
background: var(--color-yellow);
|
background: var(--color-yellow);
|
||||||
box-shadow: -5px 5px 0 var(--color-pink);
|
box-shadow: -4px 4px 0 var(--color-pink);
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
border-bottom-left-radius: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-content {
|
.q-content {
|
||||||
font-family: var(--font-title);
|
font-family: var(--font-title);
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-quote-mark {
|
.q-quote-mark {
|
||||||
position: absolute;
|
display: none;
|
||||||
font-family: serif;
|
/* Hide quote mark for cleaner chat look */
|
||||||
font-size: 4rem;
|
|
||||||
color: rgba(0, 0, 0, 0.05);
|
|
||||||
top: -20px;
|
|
||||||
left: -10px;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.q-author {
|
|
||||||
font-family: var(--font-hand);
|
|
||||||
font-weight: bold;
|
|
||||||
color: var(--ink-secondary);
|
|
||||||
font-size: 0.95rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-analysis-note {
|
.q-analysis-note {
|
||||||
background: #fffde7;
|
background: #fffde7;
|
||||||
padding: 12px 15px;
|
padding: 10px 15px;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
width: 95%;
|
width: fit-content;
|
||||||
margin-top: -8px;
|
/* Fit content */
|
||||||
|
max-width: 100%;
|
||||||
|
margin-top: -5px;
|
||||||
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
|
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
font-family: var(--font-body);
|
font-family: var(--font-body);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
border-radius: 0 0 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.quote-wrapper:nth-child(odd) .q-analysis-note {
|
.quote-wrapper:nth-child(odd) .q-analysis-note {
|
||||||
|
|||||||
@@ -8,14 +8,26 @@
|
|||||||
</div>
|
</div>
|
||||||
{% for quote in quotes %}
|
{% for quote in quotes %}
|
||||||
<div class="quote-wrapper">
|
<div class="quote-wrapper">
|
||||||
<div class="q-bubble">
|
<div class="q-flex-container">
|
||||||
<div class="q-quote-mark">"</div>
|
<div class="q-user-col">
|
||||||
<div class="q-content">{{ quote.content }}</div>
|
{% if quote.avatar_url %}
|
||||||
<div class="q-author">— {{ quote.sender }}</div>
|
<div class="q-avatar-box">
|
||||||
</div>
|
<img src="{{ quote.avatar_url }}" class="q-avatar">
|
||||||
<div class="q-analysis-note">
|
</div>
|
||||||
<span class="note-label">🤣👉 AI 锐评:</span>
|
{% endif %}
|
||||||
{{ quote.reason }}
|
</div>
|
||||||
|
|
||||||
|
<div class="q-content-col">
|
||||||
|
<div class="q-sender-name">{{ quote.sender }}</div>
|
||||||
|
<div class="q-bubble">
|
||||||
|
<div class="q-quote-mark">"</div>
|
||||||
|
<div class="q-content">{{ quote.content }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="q-analysis-note">
|
||||||
|
<span class="note-label">🤣👉 AI 锐评:</span>
|
||||||
|
{{ quote.reason }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
Reference in New Issue
Block a user