mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-02-17 16:20:05 +08:00
commit
a904becfe0
@ -529,7 +529,7 @@ class Matcher(metaclass=MatcherMeta):
|
||||
|
||||
:参数:
|
||||
|
||||
* ``message: Union[str, Message, MessageSegment]``: 消息内容
|
||||
* ``message: Union[str, Message, MessageSegment, MessageTemplate]``: 消息内容
|
||||
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||
"""
|
||||
if message is not None:
|
||||
@ -549,7 +549,7 @@ class Matcher(metaclass=MatcherMeta):
|
||||
|
||||
:参数:
|
||||
|
||||
* ``prompt: Union[str, Message, MessageSegment]``: 消息内容
|
||||
* ``prompt: Union[str, Message, MessageSegment, MessageTemplate]``: 消息内容
|
||||
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||
"""
|
||||
if prompt is not None:
|
||||
@ -570,7 +570,7 @@ class Matcher(metaclass=MatcherMeta):
|
||||
|
||||
:参数:
|
||||
|
||||
* ``prompt: Union[str, Message, MessageSegment]``: 消息内容
|
||||
* ``prompt: Union[str, Message, MessageSegment, MessageTemplate]``: 消息内容
|
||||
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||
"""
|
||||
if prompt is not None:
|
||||
@ -593,7 +593,7 @@ class Matcher(metaclass=MatcherMeta):
|
||||
:参数:
|
||||
|
||||
* ``key: str``: 参数名
|
||||
* ``prompt: Union[str, Message, MessageSegment]``: 消息内容
|
||||
* ``prompt: Union[str, Message, MessageSegment, MessageTemplate]``: 消息内容
|
||||
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||
"""
|
||||
matcher = current_matcher.get()
|
||||
@ -618,7 +618,7 @@ class Matcher(metaclass=MatcherMeta):
|
||||
:参数:
|
||||
|
||||
* ``id: str``: 消息 id
|
||||
* ``prompt: Union[str, Message, MessageSegment]``: 消息内容
|
||||
* ``prompt: Union[str, Message, MessageSegment, MessageTemplate]``: 消息内容
|
||||
* ``**kwargs``: 其他传递给 ``bot.send`` 的参数,请参考对应 adapter 的 bot 对象 api
|
||||
"""
|
||||
matcher = current_matcher.get()
|
||||
|
@ -188,7 +188,7 @@ class BotParam(Param):
|
||||
_BotChecker(
|
||||
Required,
|
||||
field=ModelField(
|
||||
name="",
|
||||
name=name,
|
||||
type_=param.annotation,
|
||||
class_validators=None,
|
||||
model_config=CustomConfig,
|
||||
@ -229,7 +229,7 @@ class EventParam(Param):
|
||||
_EventChecker(
|
||||
Required,
|
||||
field=ModelField(
|
||||
name="",
|
||||
name=name,
|
||||
type_=param.annotation,
|
||||
class_validators=None,
|
||||
model_config=CustomConfig,
|
||||
|
32
poetry.lock
generated
32
poetry.lock
generated
@ -229,7 +229,7 @@ pycparser = "*"
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "2.0.9"
|
||||
version = "2.0.10"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -344,7 +344,7 @@ python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "0.14.3"
|
||||
version = "0.14.4"
|
||||
description = "A minimal low-level HTTP client."
|
||||
category = "main"
|
||||
optional = true
|
||||
@ -372,7 +372,7 @@ test = ["Cython (==0.29.22)"]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.21.1"
|
||||
version = "0.21.3"
|
||||
description = "The next generation HTTP client."
|
||||
category = "main"
|
||||
optional = true
|
||||
@ -555,7 +555,7 @@ pytest-asyncio = "^0.16.0"
|
||||
type = "git"
|
||||
url = "https://github.com/nonebot/nonebug.git"
|
||||
reference = "master"
|
||||
resolved_reference = "e198b56be8f9ccf53c0d6de38e40fb9c0831c890"
|
||||
resolved_reference = "123916d7281a49e45a1e6b7472a682bec16290ac"
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
@ -670,7 +670,7 @@ dev = ["black", "coverage", "docformatter", "flake8", "flake8-black", "flake8-bu
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.11.1"
|
||||
version = "2.11.2"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -798,7 +798,7 @@ dotenv = ["python-dotenv"]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.27.0"
|
||||
version = "2.27.1"
|
||||
description = "Python HTTP for Humans."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@ -1452,8 +1452,8 @@ cffi = [
|
||||
{file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"},
|
||||
]
|
||||
charset-normalizer = [
|
||||
{file = "charset-normalizer-2.0.9.tar.gz", hash = "sha256:b0b883e8e874edfdece9c28f314e3dd5badf067342e42fb162203335ae61aa2c"},
|
||||
{file = "charset_normalizer-2.0.9-py3-none-any.whl", hash = "sha256:1eecaa09422db5be9e29d7fc65664e6c33bd06f9ced7838578ba40d58bdf3721"},
|
||||
{file = "charset-normalizer-2.0.10.tar.gz", hash = "sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd"},
|
||||
{file = "charset_normalizer-2.0.10-py3-none-any.whl", hash = "sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"},
|
||||
]
|
||||
click = [
|
||||
{file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"},
|
||||
@ -1611,8 +1611,8 @@ html2text = [
|
||||
{file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"},
|
||||
]
|
||||
httpcore = [
|
||||
{file = "httpcore-0.14.3-py3-none-any.whl", hash = "sha256:9a98d2416b78976fc5396ff1f6b26ae9885efbb3105d24eed490f20ab4c95ec1"},
|
||||
{file = "httpcore-0.14.3.tar.gz", hash = "sha256:d10162a63265a0228d5807964bd964478cbdb5178f9a2eedfebb2faba27eef5d"},
|
||||
{file = "httpcore-0.14.4-py3-none-any.whl", hash = "sha256:9410fe352bea732311f2b2bee0555c8cc5e62b9a73b9d3272fe125a2aa6eb28e"},
|
||||
{file = "httpcore-0.14.4.tar.gz", hash = "sha256:d4305811f604d3c2e22869147392f134796976ff946c96a8cfba87f4e0171d83"},
|
||||
]
|
||||
httptools = [
|
||||
{file = "httptools-0.2.0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5"},
|
||||
@ -1632,8 +1632,8 @@ httptools = [
|
||||
{file = "httptools-0.2.0.tar.gz", hash = "sha256:94505026be56652d7a530ab03d89474dc6021019d6b8682281977163b3471ea0"},
|
||||
]
|
||||
httpx = [
|
||||
{file = "httpx-0.21.1-py3-none-any.whl", hash = "sha256:208e5ef2ad4d105213463cfd541898ed9d11851b346473539a8425e644bb7c66"},
|
||||
{file = "httpx-0.21.1.tar.gz", hash = "sha256:02af20df486b78892a614a7ccd4e4e86a5409ec4981ab0e422c579a887acad83"},
|
||||
{file = "httpx-0.21.3-py3-none-any.whl", hash = "sha256:df9a0fd43fa79dbab411d83eb1ea6f7a525c96ad92e60c2d7f40388971b25777"},
|
||||
{file = "httpx-0.21.3.tar.gz", hash = "sha256:7a3eb67ef0b8abbd6d9402248ef2f84a76080fa1c839f8662e6eb385640e445a"},
|
||||
]
|
||||
hypercorn = [
|
||||
{file = "Hypercorn-0.13.2-py3-none-any.whl", hash = "sha256:ca18f91ab3fa823cbe9e949738f9f2cc07027cd647c80d8f93e4b1a2a175f112"},
|
||||
@ -1928,8 +1928,8 @@ pydash = [
|
||||
{file = "pydash-5.1.0.tar.gz", hash = "sha256:1b2b050ac1bae049cd07f5920b14fabbe52638f485d9ada1eb115a9eebff6835"},
|
||||
]
|
||||
pygments = [
|
||||
{file = "Pygments-2.11.1-py3-none-any.whl", hash = "sha256:9135c1af61eec0f650cd1ea1ed8ce298e54d56bcd8cc2ef46edd7702c171337c"},
|
||||
{file = "Pygments-2.11.1.tar.gz", hash = "sha256:59b895e326f0fb0d733fd28c6839bd18ad0687ba20efc26d4277fd1d30b971f4"},
|
||||
{file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"},
|
||||
{file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"},
|
||||
]
|
||||
pygtrie = [
|
||||
{file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"},
|
||||
@ -1998,8 +1998,8 @@ quart = [
|
||||
{file = "Quart-0.16.2.tar.gz", hash = "sha256:356f4fd795fbf5a7a97bdeb7ca908b5051d0e6e4c0499b2b7c30b743a6938a7e"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.27.0-py2.py3-none-any.whl", hash = "sha256:f71a09d7feba4a6b64ffd8e9d9bc60f9bf7d7e19fd0e04362acb1cfc2e3d98df"},
|
||||
{file = "requests-2.27.0.tar.gz", hash = "sha256:8e5643905bf20a308e25e4c1dd379117c09000bf8a82ebccc462cfb1b34a16b5"},
|
||||
{file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
|
||||
{file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
|
||||
]
|
||||
rfc3986 = [
|
||||
{file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"},
|
||||
|
21
tests/conftest.py
Normal file
21
tests/conftest.py
Normal file
@ -0,0 +1,21 @@
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Set
|
||||
|
||||
import pytest
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from nonebot.plugin import Plugin
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def load_plugin(nonebug_init: None) -> Set["Plugin"]:
|
||||
import nonebot
|
||||
|
||||
return nonebot.load_plugins(str(Path(__file__).parent / "plugins"))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def load_example(nonebug_init: None) -> Set["Plugin"]:
|
||||
import nonebot
|
||||
|
||||
return nonebot.load_plugins(str(Path(__file__).parent / "examples"))
|
29
tests/examples/weather.py
Normal file
29
tests/examples/weather.py
Normal file
@ -0,0 +1,29 @@
|
||||
from nonebot import on_command
|
||||
from nonebot.rule import to_me
|
||||
from nonebot.matcher import Matcher
|
||||
from nonebot.adapters import Message
|
||||
from nonebot.params import Arg, CommandArg, ArgPlainText
|
||||
|
||||
weather = on_command("weather", rule=to_me(), aliases={"天气", "天气预报"}, priority=5)
|
||||
|
||||
|
||||
@weather.handle()
|
||||
async def handle_first_receive(matcher: Matcher, args: Message = CommandArg()):
|
||||
plain_text = args.extract_plain_text() # 首次发送命令时跟随的参数,例:/天气 上海,则args为上海
|
||||
if plain_text:
|
||||
matcher.set_arg("city", args) # 如果用户发送了参数则直接赋值
|
||||
|
||||
|
||||
@weather.got("city", prompt="你想查询哪个城市的天气呢?")
|
||||
async def handle_city(city: Message = Arg(), city_name: str = ArgPlainText("city")):
|
||||
if city_name not in ["北京", "上海"]: # 如果参数不符合要求,则提示用户重新输入
|
||||
# 可以使用平台的 Message 类直接构造模板消息
|
||||
await weather.reject(city.template("你想查询的城市 {city} 暂不支持,请重新输入!"))
|
||||
|
||||
city_weather = await get_weather(city_name)
|
||||
await weather.finish(city_weather)
|
||||
|
||||
|
||||
# 在这里编写获取天气信息的函数
|
||||
async def get_weather(city: str) -> str:
|
||||
return f"{city}的天气是..."
|
64
tests/test_examples/test_weather.py
Normal file
64
tests/test_examples/test_weather.py
Normal file
@ -0,0 +1,64 @@
|
||||
import pytest
|
||||
from nonebug import App
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_weather(app: App):
|
||||
from examples.weather import weather
|
||||
from utils import make_fake_event, make_fake_message
|
||||
|
||||
# 将此处的 make_fake_message() 替换为你要发送的平台消息 Message 类型
|
||||
Message = make_fake_message()
|
||||
|
||||
async with app.test_matcher(weather) as ctx:
|
||||
bot = ctx.create_bot()
|
||||
|
||||
msg = Message("/天气 上海")
|
||||
# 将此处的 make_fake_event() 替换为你要发送的平台事件 Event 类型
|
||||
event = make_fake_event(_message=msg, _to_me=True)()
|
||||
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_send(event, "上海的天气是...", True)
|
||||
ctx.should_finished()
|
||||
|
||||
async with app.test_matcher(weather) as ctx:
|
||||
bot = ctx.create_bot()
|
||||
|
||||
msg = Message("/天气 南京")
|
||||
# 将此处的 make_fake_event() 替换为你要发送的平台事件 Event 类型
|
||||
event = make_fake_event(_message=msg, _to_me=True)()
|
||||
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_send(event, Message("你想查询的城市 南京 暂不支持,请重新输入!"), True)
|
||||
ctx.should_rejected()
|
||||
|
||||
msg = Message("北京")
|
||||
event = make_fake_event(_message=msg)()
|
||||
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_send(event, "北京的天气是...", True)
|
||||
ctx.should_finished()
|
||||
|
||||
async with app.test_matcher(weather) as ctx:
|
||||
bot = ctx.create_bot()
|
||||
|
||||
msg = Message("/天气")
|
||||
# 将此处的 make_fake_event() 替换为你要发送的平台事件 Event 类型
|
||||
event = make_fake_event(_message=msg, _to_me=True)()
|
||||
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_send(event, "你想查询哪个城市的天气呢?", True)
|
||||
|
||||
msg = Message("杭州")
|
||||
event = make_fake_event(_message=msg)()
|
||||
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_send(event, Message("你想查询的城市 杭州 暂不支持,请重新输入!"), True)
|
||||
ctx.should_rejected()
|
||||
|
||||
msg = Message("北京")
|
||||
event = make_fake_event(_message=msg)()
|
||||
|
||||
ctx.receive_event(bot, event)
|
||||
ctx.should_call_send(event, "北京的天气是...", True)
|
||||
ctx.should_finished()
|
@ -4,8 +4,6 @@ from typing import TYPE_CHECKING, Set
|
||||
|
||||
import pytest
|
||||
|
||||
from utils import load_plugin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from nonebot.plugin import Plugin
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
from nonebug import App
|
||||
|
||||
from utils import load_plugin, make_fake_event, make_fake_message
|
||||
from utils import make_fake_event, make_fake_message
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
from nonebug import App
|
||||
|
||||
from utils import load_plugin, make_fake_event, make_fake_message
|
||||
from utils import make_fake_event, make_fake_message
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
@ -1,11 +1,8 @@
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Set, Type, Optional
|
||||
from typing import TYPE_CHECKING, Type, Optional
|
||||
|
||||
import pytest
|
||||
from pydantic import create_model
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from nonebot.plugin import Plugin
|
||||
from nonebot.adapters import Event, Message
|
||||
|
||||
|
||||
@ -85,10 +82,3 @@ def make_fake_event(
|
||||
extra = "forbid"
|
||||
|
||||
return FakeEvent
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def load_plugin(nonebug_init: None) -> Set["Plugin"]:
|
||||
import nonebot
|
||||
|
||||
return nonebot.load_plugins(str(Path(__file__).parent / "plugins"))
|
||||
|
32
website/docs/tutorial/plugin/example.mdx
Normal file
32
website/docs/tutorial/plugin/example.mdx
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
sidebar_position: 6
|
||||
description: 简单插件示例
|
||||
---
|
||||
|
||||
import CodeBlock from "@theme/CodeBlock";
|
||||
import Messenger from "@site/src/components/Messenger";
|
||||
|
||||
# 插件示例
|
||||
|
||||
## 命令式问答示例
|
||||
|
||||
import WeatherSource from "!!raw-loader!../../../../tests/examples/weather.py";
|
||||
import WeatherTest from "!!raw-loader!../../../../tests/test_examples/test_weather.py";
|
||||
|
||||
<CodeBlock className="language-python">{WeatherSource}</CodeBlock>
|
||||
|
||||
<Messenger
|
||||
msgs={[
|
||||
{ position: "right", msg: "/天气" },
|
||||
{ position: "left", msg: "你想查询哪个城市的天气呢?" },
|
||||
{ position: "right", msg: "上海" },
|
||||
{ position: "left", msg: "上海的天气是..." },
|
||||
]}
|
||||
/>
|
||||
|
||||
<details>
|
||||
<summary>测试示例</summary>
|
||||
|
||||
<CodeBlock className="language-python">{WeatherTest}</CodeBlock>
|
||||
|
||||
</details>
|
@ -30,6 +30,7 @@
|
||||
"docusaurus-preset-nonepress": "canary",
|
||||
"file-loader": "^6.2.0",
|
||||
"prism-react-renderer": "^1.2.1",
|
||||
"raw-loader": "^4.0.2",
|
||||
"react": "^17.0.1",
|
||||
"react-color": "^2.19.3",
|
||||
"react-dom": "^17.0.1",
|
||||
|
105
website/src/components/Messenger/index.tsx
Normal file
105
website/src/components/Messenger/index.tsx
Normal file
@ -0,0 +1,105 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import Logo from "@theme/Logo";
|
||||
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
export type Message = {
|
||||
position?: "left" | "right";
|
||||
msg: string;
|
||||
};
|
||||
|
||||
function MessageBox({
|
||||
msg,
|
||||
isRight,
|
||||
}: {
|
||||
msg: string;
|
||||
isRight: boolean;
|
||||
}): JSX.Element {
|
||||
return (
|
||||
<div
|
||||
className={clsx(styles.message, {
|
||||
[styles.messageRight]: isRight,
|
||||
})}
|
||||
>
|
||||
{isRight ? (
|
||||
<div className={clsx("bg-cyan-600 text-base", styles.messageAvatar)}>
|
||||
<FontAwesomeIcon icon={["fas", "user"]} />
|
||||
</div>
|
||||
) : (
|
||||
<div className={clsx("transparent", styles.messageAvatar)}>
|
||||
<Logo imageClassName="h-full w-full" disabled />
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={clsx(styles.messageBox, { "order-first": isRight })}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: msg.replace(/\n/g, "<br/>").replace(/ /g, " "),
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Messenger({
|
||||
msgs = [],
|
||||
}: {
|
||||
msgs?: Message[];
|
||||
}): JSX.Element {
|
||||
const isRight = (msg: Message): boolean => msg.position === "right";
|
||||
|
||||
return (
|
||||
<div className="block w-full max-w-full my-4 rounded shadow-md outline-none no-underline bg-light-nonepress-100 dark:bg-dark-nonepress-100">
|
||||
<header className="flex items-center h-12 px-4 bg-blue-500 text-white rounded-t-[inherit]">
|
||||
<div className="text-left text-base grow">
|
||||
<FontAwesomeIcon icon={["fas", "chevron-left"]} />
|
||||
</div>
|
||||
<div className="flex-initial grow-0">
|
||||
<span className="text-xl font-bold">NoneBot</span>
|
||||
</div>
|
||||
<div className="text-right text-base grow">
|
||||
<FontAwesomeIcon icon={["fas", "user"]} />
|
||||
</div>
|
||||
</header>
|
||||
<div className="p-3 min-h-[150px]">
|
||||
{msgs.map((msg, i) => (
|
||||
<MessageBox msg={msg.msg} isRight={isRight(msg)} key={i} />
|
||||
))}
|
||||
</div>
|
||||
<div className="px-3">
|
||||
<div className="flex flex-row items-center">
|
||||
<div className="flex-1 p-1 max-w-full">
|
||||
<input className="w-full rounded bg-light dark:bg-dark" />
|
||||
</div>
|
||||
<div className="flex-initial grow-0 w-fit">
|
||||
<button className="h-7 px-3 rounded-full bg-blue-500 text-white">
|
||||
<span>发送</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row items-center text-center text-base text-gray-600">
|
||||
<div className="p-1 shrink-0 grow-0 basis-1/6">
|
||||
<FontAwesomeIcon icon={["fas", "microphone"]} />
|
||||
</div>
|
||||
<div className="p-1 shrink-0 grow-0 basis-1/6">
|
||||
<FontAwesomeIcon icon={["fas", "image"]} />
|
||||
</div>
|
||||
<div className="p-1 shrink-0 grow-0 basis-1/6">
|
||||
<FontAwesomeIcon icon={["fas", "camera"]} />
|
||||
</div>
|
||||
<div className="p-1 shrink-0 grow-0 basis-1/6">
|
||||
<FontAwesomeIcon icon={["fas", "wallet"]} />
|
||||
</div>
|
||||
<div className="p-1 shrink-0 grow-0 basis-1/6">
|
||||
<FontAwesomeIcon icon={["fas", "smile-wink"]} />
|
||||
</div>
|
||||
<div className="p-1 shrink-0 grow-0 basis-1/6">
|
||||
<FontAwesomeIcon icon={["fas", "plus-circle"]} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
30
website/src/components/Messenger/styles.module.css
Normal file
30
website/src/components/Messenger/styles.module.css
Normal file
@ -0,0 +1,30 @@
|
||||
.message {
|
||||
@apply flex flex-row flex-wrap justify-start;
|
||||
}
|
||||
|
||||
.messageRight {
|
||||
@apply justify-end;
|
||||
}
|
||||
|
||||
.message .messageAvatar {
|
||||
@apply relative inline-flex items-center justify-center text-center align-middle h-9 w-9 rounded-full;
|
||||
}
|
||||
|
||||
.message .messageBox {
|
||||
@apply relative w-fit max-w-[55%] px-2 py-[0.375rem] mx-3 my-2 rounded-lg bg-light;
|
||||
}
|
||||
:global(.dark) .message .messageBox {
|
||||
@apply bg-dark;
|
||||
}
|
||||
|
||||
.message .messageBox::after {
|
||||
content: "";
|
||||
border-bottom: 7px solid;
|
||||
@apply absolute top-0 right-full w-2 h-3 text-light rounded-bl-lg;
|
||||
}
|
||||
:global(.dark) .message .messageBox::after {
|
||||
@apply text-dark;
|
||||
}
|
||||
.message.messageRight .messageBox::after {
|
||||
@apply !left-full !right-auto !rounded-bl-[0] !rounded-br-lg;
|
||||
}
|
@ -6235,6 +6235,14 @@ raw-body@2.4.2:
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
raw-loader@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npm.taobao.org/raw-loader/download/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6"
|
||||
integrity sha1-GqxrfRrRUB5m79rBUixz5ZpYTrY=
|
||||
dependencies:
|
||||
loader-utils "^2.0.0"
|
||||
schema-utils "^3.0.0"
|
||||
|
||||
rc@^1.2.8:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.nlark.com/rc/download/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
|
Loading…
x
Reference in New Issue
Block a user