Merge branch 'master' of https://github.com/ktwrd/revite
commit
6f5fdf5bf4
|
|
@ -15,22 +15,27 @@ jobs:
|
|||
gh api graphql -f query='
|
||||
query {
|
||||
organization(login: "revoltchat"){
|
||||
projectNext(number: 3) {
|
||||
projectV2(number: 3) {
|
||||
id
|
||||
fields(first:20) {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
settings
|
||||
... on ProjectV2SingleSelectField {
|
||||
id
|
||||
name
|
||||
options {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}' > project_data.json
|
||||
|
||||
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'TODO_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="Todo") |.id' project_data.json) >> $GITHUB_ENV
|
||||
|
||||
- name: Add issue to project
|
||||
env:
|
||||
|
|
@ -39,11 +44,11 @@ jobs:
|
|||
run: |
|
||||
item_id="$( gh api graphql -f query='
|
||||
mutation($project:ID!, $issue:ID!) {
|
||||
addProjectNextItem(input: {projectId: $project, contentId: $issue}) {
|
||||
projectNextItem {
|
||||
addProjectV2ItemById(input: {projectId: $project, contentId: $issue}) {
|
||||
item {
|
||||
id
|
||||
}
|
||||
}
|
||||
}' -f project=$PROJECT_ID -f issue=$ISSUE_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
|
||||
|
||||
}' -f project=$PROJECT_ID -f issue=$ISSUE_ID --jq '.data.addProjectV2ItemById.item.id')"
|
||||
|
||||
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
|
||||
|
|
|
|||
|
|
@ -15,22 +15,27 @@ jobs:
|
|||
gh api graphql -f query='
|
||||
query {
|
||||
organization(login: "revoltchat"){
|
||||
projectNext(number: 3) {
|
||||
projectV2(number: 3) {
|
||||
id
|
||||
fields(first:20) {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
settings
|
||||
... on ProjectV2SingleSelectField {
|
||||
id
|
||||
name
|
||||
options {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}' > project_data.json
|
||||
|
||||
echo 'PROJECT_ID='$(jq '.data.organization.projectNext.id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'INCOMING_OPTION_ID='$(jq '.data.organization.projectNext.fields.nodes[] | select(.name== "Status") |.settings | fromjson.options[] | select(.name=="Incoming PRs") |.id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'PROJECT_ID='$(jq '.data.organization.projectV2.id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'STATUS_FIELD_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .id' project_data.json) >> $GITHUB_ENV
|
||||
echo 'INCOMING_OPTION_ID='$(jq '.data.organization.projectV2.fields.nodes[] | select(.name== "Status") | .options[] | select(.name=="Incoming PRs") |.id' project_data.json) >> $GITHUB_ENV
|
||||
|
||||
- name: Add PR to project
|
||||
env:
|
||||
|
|
@ -39,13 +44,13 @@ jobs:
|
|||
run: |
|
||||
item_id="$( gh api graphql -f query='
|
||||
mutation($project:ID!, $pr:ID!) {
|
||||
addProjectNextItem(input: {projectId: $project, contentId: $pr}) {
|
||||
projectNextItem {
|
||||
addProjectV2ItemById(input: {projectId: $project, contentId: $pr}) {
|
||||
item {
|
||||
id
|
||||
}
|
||||
}
|
||||
}' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectNextItem.projectNextItem.id')"
|
||||
|
||||
}' -f project=$PROJECT_ID -f pr=$PR_ID --jq '.data.addProjectV2ItemById.item.id')"
|
||||
|
||||
echo 'ITEM_ID='$item_id >> $GITHUB_ENV
|
||||
|
||||
- name: Set fields
|
||||
|
|
@ -59,14 +64,16 @@ jobs:
|
|||
$status_field: ID!
|
||||
$status_value: String!
|
||||
) {
|
||||
set_status: updateProjectNextItemField(input: {
|
||||
set_status: updateProjectV2ItemFieldValue(input: {
|
||||
projectId: $project
|
||||
itemId: $item
|
||||
fieldId: $status_field
|
||||
value: $status_value
|
||||
value: {
|
||||
singleSelectOptionId: $status_value
|
||||
}
|
||||
}) {
|
||||
projectNextItem {
|
||||
projectV2Item {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f status_field=$STATUS_FIELD_ID -f status_value=${{ env.INCOMING_OPTION_ID }} --silent
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit f95ec6dc8200adba7925425d4cf2ae0c16f049c3
|
||||
Subproject commit 4eec9dd02afa6a7f9b68c336282d4819b9c30790
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit ab064f41a4154acee7c1751ea5b59d9ee4345a0b
|
||||
Subproject commit e1a98853b49adb78698af175e8b7c971ef501d5b
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import { Link } from "react-router-dom";
|
||||
import { Channel, User } from "revolt.js";
|
||||
import { Emoji as CustomEmoji } from "revolt.js/esm/maps/Emojis";
|
||||
import styled, { css } from "styled-components/macro";
|
||||
|
||||
import { StateUpdater, useState } from "preact/hooks";
|
||||
|
|
@ -7,6 +10,8 @@ import { emojiDictionary } from "../../assets/emojis";
|
|||
import { useClient } from "../../controllers/client/ClientController";
|
||||
import ChannelIcon from "./ChannelIcon";
|
||||
import Emoji from "./Emoji";
|
||||
import ServerIcon from "./ServerIcon";
|
||||
import Tooltip from "./Tooltip";
|
||||
import UserIcon from "./user/UserIcon";
|
||||
|
||||
export type AutoCompleteState =
|
||||
|
|
@ -14,7 +19,7 @@ export type AutoCompleteState =
|
|||
| ({ selected: number; within: boolean } & (
|
||||
| {
|
||||
type: "emoji";
|
||||
matches: string[];
|
||||
matches: (string | CustomEmoji)[];
|
||||
}
|
||||
| {
|
||||
type: "user";
|
||||
|
|
@ -104,16 +109,23 @@ export function useAutoComplete(
|
|||
|
||||
if (type === "emoji") {
|
||||
// ! TODO: we should convert it to a Binary Search Tree and use that
|
||||
const matches = Object.keys(emojiDictionary)
|
||||
.filter((emoji: string) => emoji.match(regex))
|
||||
.splice(0, 5);
|
||||
const matches = [
|
||||
...Object.keys(emojiDictionary).filter((emoji: string) =>
|
||||
emoji.match(regex),
|
||||
),
|
||||
...Array.from(client.emojis.values()).filter((emoji) =>
|
||||
emoji.name.match(regex),
|
||||
),
|
||||
].splice(0, 5);
|
||||
|
||||
if (matches.length > 0) {
|
||||
const currentPosition =
|
||||
state.type !== "none" ? state.selected : 0;
|
||||
|
||||
setState({
|
||||
// @ts-ignore-next-line are you high
|
||||
type: "emoji",
|
||||
// @ts-ignore-next-line
|
||||
matches,
|
||||
selected: Math.min(currentPosition, matches.length - 1),
|
||||
within: false,
|
||||
|
|
@ -233,10 +245,13 @@ export function useAutoComplete(
|
|||
|
||||
const content = el.value.split("");
|
||||
if (state.type === "emoji") {
|
||||
const selected = state.matches[state.selected];
|
||||
content.splice(
|
||||
index,
|
||||
search.length,
|
||||
state.matches[state.selected],
|
||||
selected instanceof CustomEmoji
|
||||
? selected._id
|
||||
: selected,
|
||||
": ",
|
||||
);
|
||||
} else if (state.type === "user") {
|
||||
|
|
@ -388,12 +403,17 @@ export default function AutoComplete({
|
|||
setState,
|
||||
onClick,
|
||||
}: Pick<AutoCompleteProps, "detached" | "state" | "setState" | "onClick">) {
|
||||
const client = useClient();
|
||||
return (
|
||||
<Base detached={detached}>
|
||||
<div>
|
||||
{state.type === "emoji" &&
|
||||
state.matches.map((match, i) => (
|
||||
<button
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
key={match}
|
||||
className={i === state.selected ? "active" : ""}
|
||||
onMouseEnter={() =>
|
||||
|
|
@ -412,15 +432,61 @@ export default function AutoComplete({
|
|||
})
|
||||
}
|
||||
onClick={onClick}>
|
||||
<Emoji
|
||||
emoji={
|
||||
(emojiDictionary as Record<string, string>)[
|
||||
match
|
||||
]
|
||||
}
|
||||
size={20}
|
||||
/>
|
||||
:{match}:
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
}}>
|
||||
{match instanceof CustomEmoji ? (
|
||||
<img
|
||||
loading="lazy"
|
||||
src={match.imageURL}
|
||||
style={{
|
||||
width: `20px`,
|
||||
height: `20px`,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Emoji
|
||||
emoji={
|
||||
(
|
||||
emojiDictionary as Record<
|
||||
string,
|
||||
string
|
||||
>
|
||||
)[match]
|
||||
}
|
||||
size={20}
|
||||
/>
|
||||
)}
|
||||
<span style={{ paddingLeft: "4px" }}>{`:${
|
||||
match instanceof CustomEmoji
|
||||
? match.name
|
||||
: match
|
||||
}:`}</span>
|
||||
</div>
|
||||
{match instanceof CustomEmoji &&
|
||||
match.parent.type == "Server" && (
|
||||
<>
|
||||
<Tooltip
|
||||
content={
|
||||
client.servers.get(
|
||||
match.parent.id,
|
||||
)?.name
|
||||
}>
|
||||
<Link
|
||||
to={`/server/${match.parent.id}`}>
|
||||
<ServerIcon
|
||||
target={client.servers.get(
|
||||
match.parent.id,
|
||||
)}
|
||||
size={20}
|
||||
/>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
{state.type === "user" &&
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ export default function Embed({ embed }: Props) {
|
|||
break;
|
||||
}
|
||||
case "Twitch":
|
||||
case "Lightspeed": {
|
||||
case "Lightspeed":
|
||||
case "Streamable": {
|
||||
mw = 1280;
|
||||
mh = 720;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,16 @@ export default function EmbedMedia({ embed, width, height }: Props) {
|
|||
/>
|
||||
);
|
||||
}
|
||||
case "Streamable": {
|
||||
return (
|
||||
<iframe
|
||||
src={`https://streamable.com/e/${embed.special.id}?loop=0`}
|
||||
seamless
|
||||
loading="lazy"
|
||||
style={{ height }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default: {
|
||||
if (embed.video) {
|
||||
const url = embed.video.url;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const Emoji = styled.img`
|
|||
}
|
||||
`;
|
||||
|
||||
const RE_EMOJI = /:([a-zA-Z0-9_+]+):/g;
|
||||
const RE_EMOJI = /:([a-zA-Z0-9\-_]+):/g;
|
||||
const RE_ULID = /^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$/;
|
||||
|
||||
export function RenderEmoji({ match }: CustomComponentProps) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ const ALLOWED_ORIGINS = [
|
|||
"app.revolt.chat",
|
||||
"nightly.revolt.chat",
|
||||
"local.revolt.chat",
|
||||
"rolt.chat",
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -59,10 +59,12 @@ export default class Draft implements Store, Persistent<Data> {
|
|||
* @param channel Channel ID
|
||||
*/
|
||||
@computed has(channel: string) {
|
||||
return (
|
||||
this.drafts.has(channel) &&
|
||||
this.drafts.get(channel)!.content!.length > 0
|
||||
);
|
||||
if (!this.drafts.has(channel)) return false;
|
||||
// fetch the draft object
|
||||
const potentialDraft = this.drafts.get(channel)?.content;
|
||||
// if it doesn't have any content return false
|
||||
if (!potentialDraft) return false;
|
||||
return potentialDraft.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -340,11 +340,13 @@ function ListElement({
|
|||
|
||||
const save = useCallback(() => {
|
||||
setEditing(undefined);
|
||||
setTitle!(editing!);
|
||||
if (editing !== "") {
|
||||
setTitle!(editing!);
|
||||
}
|
||||
}, [editing, setTitle]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editing) return;
|
||||
if (editing === undefined) return;
|
||||
|
||||
function onClick(ev: MouseEvent) {
|
||||
if ((ev.target as HTMLElement)?.id !== category.id) {
|
||||
|
|
@ -368,7 +370,7 @@ function ListElement({
|
|||
<div className="inner">
|
||||
<Row>
|
||||
<KanbanListHeader {...provided.dragHandleProps}>
|
||||
{editing ? (
|
||||
{editing !== undefined ? (
|
||||
<input
|
||||
value={editing}
|
||||
onChange={(e) =>
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ export const Roles = observer(({ server }: Props) => {
|
|||
}
|
||||
`;
|
||||
|
||||
const DeleteRoleButton = styled(Button)`
|
||||
margin: 16px 0;
|
||||
`;
|
||||
|
||||
return (
|
||||
<PermissionsLayout
|
||||
server={server}
|
||||
|
|
@ -266,12 +270,12 @@ export const Roles = observer(({ server }: Props) => {
|
|||
<h1>
|
||||
<Text id="app.settings.categories.danger_zone" />
|
||||
</h1>
|
||||
<Button
|
||||
<DeleteRoleButton
|
||||
palette="error"
|
||||
compact
|
||||
onClick={deleteRole}>
|
||||
<Text id="app.settings.permissions.delete_role" />
|
||||
</Button>
|
||||
</DeleteRoleButton>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
10
yarn.lock
10
yarn.lock
|
|
@ -8016,14 +8016,14 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"revolt-api@npm:0.5.5-4":
|
||||
version: 0.5.5-4
|
||||
resolution: "revolt-api@npm:0.5.5-4"
|
||||
"revolt-api@npm:0.5.7":
|
||||
version: 0.5.7
|
||||
resolution: "revolt-api@npm:0.5.7"
|
||||
dependencies:
|
||||
"@insertish/oapi": 0.1.18
|
||||
axios: ^0.26.1
|
||||
lodash.defaultsdeep: ^4.6.1
|
||||
checksum: dfb374d58f1b8b5a6de2e7fa05e386b3df3ffb85a450a6894f23c6b9760af8bff0d198d8352063c33084f0dbc6ff84a234300efb0c62c7b27f709887402787f1
|
||||
checksum: ce5d24f1f71c039789b71c33cce12a9bc1ee4709e2c37f88ac95caff193096ff4f5e90fd48ba0ed6f6bbb71d080cd410f8ba8a3998da8bd8083766a016b18306
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -8040,7 +8040,7 @@ __metadata:
|
|||
lodash.isequal: ^4.5.0
|
||||
long: ^5.2.0
|
||||
mobx: ^6.3.2
|
||||
revolt-api: 0.5.5-4
|
||||
revolt-api: 0.5.7
|
||||
ulid: ^2.3.0
|
||||
ws: ^8.2.2
|
||||
languageName: node
|
||||
|
|
|
|||
Loading…
Reference in New Issue