Skip to content

Commit

Permalink
feat: Localization 🌐 (#64)
Browse files Browse the repository at this point in the history
* chore: Add Schema Lang

* chore: Renew schema

* chore: Renew Schema

* chore: Implement

* chore(lang): First try on command runner

* refactor: Add usefull comment

* chore(lang): Implement on Argument parser

* chore(lang): Implement on base type

* chore(lang): Implement on Animals Command

* refactor: Add emoji because koretekawaidesu!

* chore(lang): Random response trans on 8ball

* chore(lang): 9% Fun command

* chore(lang): Fun 10%

* chore(lang): All general command

* chore(lang): 20% Fun Command

* refactor: Change the post

* chore(lang): Complete Music Module

* feat: Add command to set lang

* refactor(lang): Animal description

* refactor(lang): remove type

* chore(cat): Add aliases kitty

* refactor(lang): Translate game desc

* feat: Adding Sunda language
  • Loading branch information
youKnowOwO authored Sep 1, 2020
1 parent ddd90bb commit 734f735
Show file tree
Hide file tree
Showing 60 changed files with 1,061 additions and 233 deletions.
86 changes: 57 additions & 29 deletions assets/json/8ball.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
[
"It is decidedly so",
"Without a doubt",
"Yes, definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes",
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again",
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful",
"Maybe?",
"no",
"Very Likely",
"Probably No",
"πŸ˜‡Only God Knows.",
"πŸ™„hmmm...",
"πŸ˜†, What is your question?",
"πŸ€”Don't see what happening!"
]
{
"en_US": [
"It is decidedly so",
"Without a doubt",
"Yes, definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes",
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again",
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful",
"Maybe?",
"no",
"Very Likely",
"Probably No",
"πŸ˜‡Only God Knows.",
"πŸ™„hmmm...",
"πŸ˜†, What is your question?",
"πŸ€”Don't see what happening!"
],
"id_ID": [
"Ini sudah pasti",
"Ya, tanpa keraguan!",
"Ya tentu saja!",
"Kamu mungkin bergantung padanya",
"Seperti yang kulihat ya!",
"Hampir",
"Ya",
"Kurasa ya",
"Emm coba lagi",
"Tanya lagi nanti",
"Bukan saatnya untuk memberi tahu mu",
"Tidak terprediksi",
"Kosentrasi dan bertanya lagi!",
"Jangan anggap itu",
"Jawaban ku adalah tidak",
"Core ku menjawab tidak",
"Sangat meragukan",
"Mungkin?",
"Tidak",
"Mungkin No",
"πŸ˜‡Hanya tuhan yang tahu.",
"πŸ™„hmmm...",
"πŸ˜†Apa pertanyaan mu?",
"πŸ€”Tidak melihat apa yang terjadi!"
]
}
3 changes: 2 additions & 1 deletion assets/json/help.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"fun": "🎭 | Fun",
"reactions": "πŸ€— | Reactions",
"music": "🎡 | Music",
"nsfw": "πŸ”ž | NSFW"
"nsfw": "πŸ”ž | NSFW",
"admin": "πŸ”¨ | Admin Only"
}
2 changes: 2 additions & 0 deletions src/classes/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Context from "@yumeko/libs/MessageContext";
import Logger from "@yumeko/libs/Logger";
import eventLoader from "@yumeko/libs/EventLoader";
import nowPlayMoe from "@yumeko/libs/NowplayMoeWS";
import { langCollector } from "@yumeko/libs/Localization";
import { Client } from "discord.js";
import { Node as Lavalink } from "lavalink";

Expand All @@ -28,6 +29,7 @@ export default class YumekoClient extends Client {
});
public nowplayMoe = nowPlayMoe;
public config = config;
public langs = langCollector();
public constructor() {
super({
fetchAllMembers: true,
Expand Down
58 changes: 58 additions & 0 deletions src/commands/Admin/Language.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import YumekoClient from "@yumeko/classes/Client";
import Command from "@yumeko/classes/Command";
import type { Message } from "discord.js";
import { DeclareCommand } from "@yumeko/decorators";
import CustomError from "@yumeko/classes/CustomError";
import { oneLineTrim } from "common-tags";

@DeclareCommand("language", {
aliases: ["language", "lang", "setlang", "locale"],
description: {
content: (msg): string => msg.guild!.loc.get("COMMAND_LANGUAGE_DESCRIPTION"),
usage: "language [lang]",
examples: ["language", "language id_ID", "language 1"]
},
category: "admin",
permissions: {
user: ["MANAGE_GUILD"]
},
args: [
{
identifier: "language",
match: "single",
type: (msg, content): string => {
const { langs } = msg.client as YumekoClient;
let lang: string | void;
if (!isNaN(Number(content))) lang = langs.keyArray()[Number(content) - 1];
else if (langs.has(content)) lang = content;
if (!lang) throw new CustomError("!PARSING", msg.guild!.loc.get("COMMAND_LANGUAGE_NOT_FOUND", content));
return lang;
},
optional: true
}
]
})
export default class extends Command {
public async exec(msg: Message, { language }: { language?: string }): Promise<Message> {
if (language) {
msg.guild!.loc.lang = language;
const currentLang: [string, string] = [
msg.guild!.loc.get("META_NAME"),
msg.guild!.loc.get("META_EMOJI")
];
return msg.ctx.send(msg.guild!.loc.get("COMMAND_LANGUAGE_SET", ...currentLang));
}
const currentLang: [string, string] = [
msg.guild!.loc.get("META_NAME"),
msg.guild!.loc.get("META_EMOJI")
];
let index = 0;
const list = this.client.langs.map((x, i) => oneLineTrim`
\`${++index}.\`
**${x.META_NAME()}**
\`${i}\`
${x.META_EMOJI()}
`).join("\n");
return msg.ctx.send(msg.guild!.loc.get("COMMAND_LANGUAGE_LIST", msg.prefix!, list, ...currentLang));
}
}
6 changes: 3 additions & 3 deletions src/commands/Animals/Bunny.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import type YumekoClient from "@yumeko/classes/Client";
import Command from "@yumeko/classes/Command";
import request from "node-superfetch";
import { MessageEmbed, Message } from "discord.js";
import { firstUpperCase } from "@yumeko/util/Util";
import { Animals } from "@yumeko/langs/en_US";

export default class BunnyCommand extends Command {
public constructor (client: YumekoClient, animal = "bunny") {
super(client, animal, {
aliases: [animal],
description: {
content: `Random ${firstUpperCase(animal)} image.`,
content: (msg): string => msg.guild!.loc.get("COMMAND_ANIMAL_DESCRIPTION", Animals[animal as any] as unknown as number),
usage: animal,
examples: [animal]
},
Expand All @@ -25,7 +25,7 @@ export default class BunnyCommand extends Command {
const embed = new MessageEmbed()
.setColor(this.client.config.color)
.setURL(image)
.setTitle("Click here if image failed to load")
.setTitle(msg.guild!.loc.get("COMMAND_ANIMAL_CLICK_HERE"))
.setImage(image);
return msg.ctx.send(embed);
}
Expand Down
6 changes: 3 additions & 3 deletions src/commands/Animals/Cat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import type { Message } from "discord.js";
import { DeclareCommand } from "@yumeko/decorators";

@DeclareCommand("cat", {
aliases: ["cat"],
aliases: ["cat", "kitty"],
description: {
content: "Random Cat image.",
content: (msg): string => msg.guild!.loc.get("COMMAND_ANIMAL_DESCRIPTION", 2),
usage: "cat",
examples: ["cat", "kitty"]
examples: ["cat"]
},
permissions: {
client: ["ATTACH_FILES"]
Expand Down
7 changes: 4 additions & 3 deletions src/commands/Fun/8Ball.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import type YumekoClient from "@yumeko/classes/Client";
import Command from "@yumeko/classes/Command";
import type { Message } from "discord.js";

const responses = require("../../../assets/json/8ball.json");
const eightBallResponse: {[key: string]: string[]} = require("../../../assets/json/8ball.json");

export default class EightBallCommand extends Command {
public constructor (client: YumekoClient) {
super(client, "8ball", {
aliases: ["8ball"],
description: {
content: "Ask to the magic 8ball",
content: (msg): string => msg.guild!.loc.get("COMMAND_8BALL_DESCRIPTION"),
usage: "8ball <question>",
examples: ["8ball are you right ?"]
},
Expand All @@ -18,14 +18,15 @@ export default class EightBallCommand extends Command {
{
identifier: "text",
match: "rest",
prompt: "What question do you want to ask ?",
prompt: (msg): string => msg.guild!.loc.get("COMMAND_8BALL_PROMPT"),
type: "string"
}
]
});
}

public exec(msg: Message): Promise<Message> {
const responses = eightBallResponse[msg.guild!.loc.lang] || eightBallResponse.en_US;
const response = responses[Math.round(Math.random()*responses.length)] || responses[0];
return msg.ctx.send(`🎱 **| ${response}**`);
}
Expand Down
4 changes: 2 additions & 2 deletions src/commands/Fun/Banana.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { join } from "path";
@DeclareCommand("banana", {
aliases: ["banana", "banana-length"],
description: {
content: "See user banana length",
content:(msg): string => msg.guild!.loc.get("COMMAND_BANANA_DESCRIPTION"),
usage: "banana [user]",
examples: ["banana", "banana @unknown"]
},
Expand All @@ -26,7 +26,7 @@ export default class BananaCommand extends Command {
if (!member) member = msg.member!;
const length = Math.floor(Math.random() * 15) + 5;
const attachment = await this.makeImage(length);
return msg.ctx.send(`🍌 **| \`${member.displayName}\` banana length is \`${length}cm\`**`, { files: [{ attachment, name: "banana.jpg" }]});
return msg.ctx.send(msg.guild!.loc.get("COMMAND_BANANA_LENGTH", member, length), { files: [{ attachment, name: "banana.jpg" }]});
}

public async makeImage(length: number): Promise<Buffer> {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/Fun/Chucknorris.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class ChucknorrisCommand extends Command {
super(client, "chucknorris", {
aliases: ["chucknorris"],
description: {
content: "Get random Chuck Norris joke",
content: (msg): string => msg.guild!.loc.get("COMMAND_CHUCKNORRIS_DESCRIPTION"),
usage: "chucknorris",
examples: ["chucknorris"]
},
Expand Down
2 changes: 1 addition & 1 deletion src/commands/Fun/Dadjoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class DadjokeCommand extends Command {
super(client, "dadjoke", {
aliases: ["dadjoke"],
description: {
content: "Get random dad joke",
content: (msg): string => msg.guild!.loc.get("COMMAND_DADJOKE_DESCRIPTION"),
usage: "dadjoke",
examples: ["dadjoke"]
},
Expand Down
4 changes: 2 additions & 2 deletions src/commands/Fun/FortuneCookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { join } from "path";
@DeclareCommand("fortune-cookie", {
aliases: ["fortune-cookie", "fortune"],
description: {
content: "crack your cookie and get the fortune.",
content: (msg): string => msg.guild!.loc.get("COMMAND_FORTUNE_COOKIE_DESCRIPTION"),
usage: "fortune-cookie",
examples: ["fortune-cookie"]
},
Expand Down Expand Up @@ -38,7 +38,7 @@ export default class FortuneCookieCommand extends Command {
}

public async exec(msg: Message): Promise<Message> {
const m = await msg.channel.send("πŸ–ŒοΈ **| Painting...**");
const m = await msg.channel.send(msg.guild!.loc.get("COMMAND_FUN_PAINTING"));
const fortune = await this.getFortune();
const attachment = await this.createImage(fortune);
m.delete();
Expand Down
14 changes: 7 additions & 7 deletions src/commands/Fun/Games/Connect4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const numbers = ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣
@DeclareCommand("game-connect4", {
aliases: [],
description: {
content: "Play Connect4 game with other user. This is solved game, you must drop 4 marks horizontal vertical or diagonal to win the match.",
content: (msg): string => msg.guild!.loc.get("COMMAND_GAME_CONNECT4_DESCRIPTION"),
usage: "<user>",
examples: ["game-conmect4"],
adionalInfo: ["<:connect4:745791911218118706> Connect4", "connect4", "c4"]
Expand All @@ -29,25 +29,25 @@ const numbers = ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣
export default class Connect4Command extends Command {
public async exec(msg: Message, { opponent }: { opponent?: User }): Promise<Message> {
if (opponent) {
const verifyMsg = await msg.channel.send(`❓ **| ${opponent}, Do you want accept this challenge ?**`);
const verifyMsg = await msg.channel.send(msg.guild!.loc.get("COMMAND_GAME_VERIFY_WAIT", opponent));
const verified = await verify(verifyMsg, opponent);
if (!verified) {
await verifyMsg.edit(`πŸƒ **| Look like ${opponent} doesn't accept your challenge. Do you want to play it with me anyway ?**`);
await verifyMsg.edit(msg.guild!.loc.get("COMMAND_GAME_VERIFY_NOT_ACCEPT", opponent, true));
const accept = await verify(verifyMsg, msg.author);
if (!accept) {
msg.ctx.send("βœ‹ **| Ok see you next time**");
msg.ctx.send(msg.guild!.loc.get("COMMAND_GAME_VERIFY_DECLINE_OFFER"));
throw new CustomError("CANCELED");
}
opponent = this.client.user!;
}
} else opponent = this.client.user!;
const message = await msg.channel.send("πŸ–ŒοΈ **| Preparing**");
const message = await msg.channel.send(msg.guild!.loc.get("COMMAND_GAME_LIST_PREPARING"));
for (const num of numbers) await message.react(num);
const c4 = new Connect4();
while(!c4.isEnd()) {
const user = c4.turn ? msg.author : opponent;
await message.edit(stripIndents`
<:connect4:745791911218118706> **| ${user}, Turn!**
<:connect4:745791911218118706> **| ${msg.guild!.loc.get("COMMAND_GAME_LIST_TURN", user)}**
> ${c4.toString().replace(/\n/g, "\n> ")}
> ${numbers.join("")}
`);
Expand All @@ -68,7 +68,7 @@ export default class Connect4Command extends Command {
c4.place(index);
}
return message.edit(stripIndents`
${c4.winner ? `πŸŽ‰ **| Congrats ${c4.turn ? msg.author : opponent}, you win the match!**` : "πŸ‡΄ **| Draw!**"}
${msg.guild!.loc.get(c4.winner ? "COMMAND_GAME_LIST_CONGRATS" : "COMMAND_GAME_LIST_DRAW", c4.turn ? msg.author : opponent)}
> ${c4.toString().replace(/\n/g, "\n> ")}
> ${numbers.join("")}
`);
Expand Down
Loading

0 comments on commit 734f735

Please sign in to comment.