Merge branch 'develop' of https://codeberg.org/calckey/calckey into note-improvements

This commit is contained in:
Freeplay 2023-02-05 19:18:35 -05:00
commit 5c9ff73b0a
14 changed files with 10305 additions and 33 deletions

View File

@ -11,10 +11,5 @@ pipeline:
password: password:
# Secret 'docker_password' needs to be set in the CI settings # Secret 'docker_password' needs to be set in the CI settings
from_secret: docker_password from_secret: docker_password
when:
# Push new version of tag latest if new push on main-branch
event: push
branch: main
depends_on: branch: main
- prSecurityCheck

View File

@ -17,5 +17,3 @@ pipeline:
event: tag event: tag
tag: v* tag: v*
depends_on:
- prSecurityCheck

10286
CHANGELOG.md

File diff suppressed because it is too large Load Diff

View File

@ -816,6 +816,7 @@ lastCommunication: "Last communication"
resolved: "Resolved" resolved: "Resolved"
unresolved: "Unresolved" unresolved: "Unresolved"
breakFollow: "Remove follower" breakFollow: "Remove follower"
breakFollowConfirm: "Are you sure want to remove follower?"
itsOn: "Enabled" itsOn: "Enabled"
itsOff: "Disabled" itsOff: "Disabled"
emailRequiredForSignup: "Require email address for sign-up" emailRequiredForSignup: "Require email address for sign-up"

View File

@ -816,6 +816,7 @@ lastCommunication: "直近の通信"
resolved: "解決済み" resolved: "解決済み"
unresolved: "未解決" unresolved: "未解決"
breakFollow: "フォロワーを解除" breakFollow: "フォロワーを解除"
breakFollowConfirm: "フォロワー解除しますか?"
itsOn: "オンになっています" itsOn: "オンになっています"
itsOff: "オフになっています" itsOff: "オフになっています"
emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする" emailRequiredForSignup: "アカウント登録にメールアドレスを必須にする"

View File

@ -1,6 +1,6 @@
{ {
"name": "calckey", "name": "calckey",
"version": "13.1.0", "version": "13.1.1",
"codename": "aqua", "codename": "aqua",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -2,9 +2,9 @@ export function nyaize(text: string): string {
return ( return (
text text
// ja-JP // ja-JP
.replace(/な/g, "にゃ") .replaceAll("な", "にゃ")
.replace(/ナ/g, "ニャ") .replaceAll("ナ", "ニャ")
.replace(/ナ/g, "ニャ") .replaceAll("ナ", "ニャ")
// en-US // en-US
.replace(/(?<=n)a/gi, (x) => (x === "A" ? "YA" : "ya")) .replace(/(?<=n)a/gi, (x) => (x === "A" ? "YA" : "ya"))
.replace(/(?<=morn)ing/gi, (x) => (x === "ING" ? "YAN" : "yan")) .replace(/(?<=morn)ing/gi, (x) => (x === "ING" ? "YAN" : "yan"))

View File

@ -35,6 +35,12 @@ export function convertLegacyReactions(reactions: Record<string, number>) {
} else { } else {
_reactions[legacies[reaction]] = reactions[reaction]; _reactions[legacies[reaction]] = reactions[reaction];
} }
} else if (reaction === "♥️") {
if (_reactions["❤️"]) {
_reactions["❤️"] += reactions[reaction];
} else {
_reactions["❤️"] = reactions[reaction];
}
} else { } else {
if (_reactions[reaction]) { if (_reactions[reaction]) {
_reactions[reaction] += reactions[reaction]; _reactions[reaction] += reactions[reaction];
@ -61,14 +67,16 @@ export async function toDbReaction(
reacterHost = toPunyNullable(reacterHost); reacterHost = toPunyNullable(reacterHost);
// 文字列タイプのリアクションを絵文字に変換 // Convert string-type reactions to unicode
if (Object.keys(legacies).includes(reaction)) return legacies[reaction]; if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
// Convert old heart to new
if (reaction === "♥️") return "❤️";
// Unicode絵文字 // Allow unicode reactions
const match = emojiRegex.exec(reaction); const match = emojiRegex.exec(reaction);
if (match) { if (match) {
const unicode = match[0]; const unicode = match[0];
return unicode.match("\u200d") ? unicode : unicode.replace(/\ufe0f/g, ""); return unicode;
} }
const custom = reaction.match(/^:([\w+-]+)(?:@\.)?:$/); const custom = reaction.match(/^:([\w+-]+)(?:@\.)?:$/);

View File

@ -93,7 +93,7 @@ export default define(meta, paramDef, async (ps, me) => {
try { try {
if (ps.tag) { if (ps.tag) {
if (!safeForSql(ps.tag)) throw new Error("Injection"); if (!safeForSql(normalizeForSearch(ps.tag))) throw "Injection";
query.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`); query.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`);
} else { } else {
query.andWhere( query.andWhere(
@ -102,7 +102,8 @@ export default define(meta, paramDef, async (ps, me) => {
qb.orWhere( qb.orWhere(
new Brackets((qb) => { new Brackets((qb) => {
for (const tag of tags) { for (const tag of tags) {
if (!safeForSql(tag)) throw new Error("Injection"); if (!safeForSql(normalizeForSearch(ps.tag)))
throw "Injection";
qb.andWhere(`'{"${normalizeForSearch(tag)}"}' <@ note.tags`); qb.andWhere(`'{"${normalizeForSearch(tag)}"}' <@ note.tags`);
} }
}), }),

View File

@ -209,12 +209,12 @@ export default async function (
await Blockings.delete(blocking.id); await Blockings.delete(blocking.id);
} else { } else {
// それ以外は単純に例外 // それ以外は単純に例外
if (blocking != null) if (blocking)
throw new IdentifiableError( throw new IdentifiableError(
"710e8fb0-b8c3-4922-be49-d5d93d8e6a6e", "710e8fb0-b8c3-4922-be49-d5d93d8e6a6e",
"blocking", "blocking",
); );
if (blocked != null) if (blocked)
throw new IdentifiableError( throw new IdentifiableError(
"3338392a-f764-498d-8855-db939dcf8c48", "3338392a-f764-498d-8855-db939dcf8c48",
"blocked", "blocked",

View File

@ -38,8 +38,8 @@ export default async function (
}), }),
]); ]);
if (blocking != null) throw new Error("blocking"); if (blocking) throw new Error("blocking");
if (blocked != null) throw new Error("blocked"); if (blocked) throw new Error("blocked");
const followRequest = await FollowRequests.insert({ const followRequest = await FollowRequests.insert({
id: genId(), id: genId(),

View File

@ -316,7 +316,7 @@ function done(query?: any): boolean | void {
if (query == null) query = q.value; if (query == null) query = q.value;
if (query == null || typeof query !== 'string') return; if (query == null || typeof query !== 'string') return;
const q2 = query.replace(/:/g, ''); const q2 = query.replaceAll(':', '');
const exactMatchCustom = customEmojis.find(emoji => emoji.name === q2); const exactMatchCustom = customEmojis.find(emoji => emoji.name === q2);
if (exactMatchCustom) { if (exactMatchCustom) {
chosen(exactMatchCustom); chosen(exactMatchCustom);

View File

@ -1496,7 +1496,7 @@
{ "category": "symbols", "char": "🀄", "name": "mahjong", "keywords": ["game", "play", "chinese", "kanji"] }, { "category": "symbols", "char": "🀄", "name": "mahjong", "keywords": ["game", "play", "chinese", "kanji"] },
{ "category": "symbols", "char": "♠️", "name": "spades", "keywords": ["poker", "cards", "suits", "magic"] }, { "category": "symbols", "char": "♠️", "name": "spades", "keywords": ["poker", "cards", "suits", "magic"] },
{ "category": "symbols", "char": "♣️", "name": "clubs", "keywords": ["poker", "cards", "magic", "suits"] }, { "category": "symbols", "char": "♣️", "name": "clubs", "keywords": ["poker", "cards", "magic", "suits"] },
{ "category": "symbols", "char": "", "name": "hearts", "keywords": ["poker", "cards", "magic", "suits"] }, { "category": "symbols", "char": "", "name": "hearts", "keywords": ["poker", "cards", "magic", "suits"] },
{ "category": "symbols", "char": "♦️", "name": "diamonds", "keywords": ["poker", "cards", "magic", "suits"] }, { "category": "symbols", "char": "♦️", "name": "diamonds", "keywords": ["poker", "cards", "magic", "suits"] },
{ "category": "symbols", "char": "🎴", "name": "flower_playing_cards", "keywords": ["game", "sunset", "red"] }, { "category": "symbols", "char": "🎴", "name": "flower_playing_cards", "keywords": ["game", "sunset", "red"] },
{ "category": "symbols", "char": "💭", "name": "thought_balloon", "keywords": ["bubble", "cloud", "speech", "thinking", "dream"] }, { "category": "symbols", "char": "💭", "name": "thought_balloon", "keywords": ["bubble", "cloud", "speech", "thinking", "dream"] },

View File

@ -192,6 +192,8 @@ export function getUserMenu(user, router: Router = mainRouter) {
} }
async function invalidateFollow() { async function invalidateFollow() {
if (!(await getConfirmed(i18n.ts.breakFollowConfirm))) return;
os.apiWithDialog("following/invalidate", { os.apiWithDialog("following/invalidate", {
userId: user.id, userId: user.id,
}).then(() => { }).then(() => {