/ src / utils / functions.ts
functions.ts
  1  import {
  2      ActionRowBuilder,
  3      AnyComponentBuilder,
  4      AttachmentBuilder,
  5      BaseInteraction,
  6      ButtonBuilder,
  7      Client,
  8      GuildMember,
  9      TextChannel,
 10      VoiceChannel
 11  } from 'discord.js';
 12  import { emojis } from './configs.json';
 13  import { loops } from './maps';
 14  import { Langs, localizationBuilder, localizationsType } from '../langs/Manager';
 15  import { log4js } from 'amethystjs';
 16  import { stations } from '../cache/stations';
 17  import { stationType } from '../typings/firebase';
 18  
 19  
 20  export const inviteLink = (client: Client) => {
 21      return `https://discord.com/api/oauth2/authorize?client_id=${client.user.id}&permissions=2184464640&scope=bot%20applications.commands`;
 22  };
 23  export const formatTime = (timeInSeconds: number, interaction: BaseInteraction): string => {
 24      let seconds = 0;
 25      let minutes = 0;
 26      let hours = 0;
 27  
 28      for (let i = 0; i < timeInSeconds; i++) {
 29          seconds++;
 30          if (seconds === 60) {
 31              minutes++;
 32              seconds = 0;
 33              if (minutes === 60) {
 34                  hours++;
 35                  minutes = 0;
 36              }
 37          }
 38      }
 39      let res = '';
 40      const values: string[] = [];
 41      [
 42          { x: hours, y: interaction.client.langs.getText(interaction, 'formatTime', 'hours') },
 43          { x: minutes, y: interaction.client.langs.getText(interaction, 'formatTime', 'minutes') },
 44          { x: seconds, y: interaction.client.langs.getText(interaction, 'formatTime', 'seconds') }
 45      ]
 46          .filter((x) => x.x > 0)
 47          .forEach((x) => {
 48              values.push(`${x.x} ${x.x === 1 ? x.y.substring(0, x.y.length - 1) : x.y}`);
 49          });
 50  
 51      values.forEach((v, i) => {
 52          res += `${v}`;
 53          const next = values[i + 1];
 54          if (!next) return;
 55          const dnext = values[i + 2];
 56          let sep = dnext ? ',' : ' ' + interaction.client.langs.getText(interaction, 'formatTime', 'joiner');
 57          res += sep + ' ';
 58      });
 59      return res;
 60  };
 61  export const isUserAlone = (channel: VoiceChannel) => {
 62      return (channel?.members?.filter((x) => !x.user.bot)?.size ?? 0) === 1;
 63  };
 64  export const checkForEnv = () => {
 65      if (!process.env.token && !process.env.beta_token) {
 66          throw new Error('Token or beta_token is missing in .env file');
 67      }
 68      if (!process.env.botOwner) {
 69          throw new Error('botOwner is missing in .env file');
 70      }
 71      if (!process.env.panelChannel) {
 72          throw new Error('panelChannel is missing in .env file');
 73      }
 74  };
 75  export const boolEmojis = (b: boolean) => emojis[b ? 'online' : 'dnd'];
 76  export const findEmoji = (txt: string) => {
 77      const chars = "'" + 'abcdefghijklmnopqrstuvwxyz0123456798-_"()[]{}*.,?!:/;%ùø&éà@^\\|è~ ';
 78      let uniques = [];
 79  
 80      for (const c of txt) {
 81          if (!chars.includes(c.toLowerCase())) uniques.push(c);
 82      }
 83      if (uniques.length === 0) return '';
 84      if (uniques.length === 1) return uniques[0];
 85  
 86      uniques = uniques.sort((a, b) => txt.indexOf(a) - txt.indexOf(b)).reverse();
 87      if (uniques.length === 2) return uniques[1];
 88      return uniques[0];
 89  };
 90  export const getLoopState = (guildId: string) => {
 91      return loops.get(guildId) ?? false;
 92  };
 93  export const setLoopState = (guildId: string, state: boolean) => {
 94      return loops.set(guildId, state);
 95  };
 96  export const row = <T extends AnyComponentBuilder = ButtonBuilder>(...components: T[]) => {
 97      return new ActionRowBuilder({
 98          components: components
 99      }) as ActionRowBuilder<T>;
100  };
101  export const resizeStr = (str: string, size?: number) => {
102      const max = size ?? 100;
103      if (str.length <= max) return str;
104      return str.substring(0, size - 3) + '...';
105  };
106  export const isLofIManager = (member: GuildMember) => member.roles.cache.some(x => x.name === 'lofi')
107  export const autoDump = async(client: Client) => {
108      const now = new Date();
109      const date = `${now.getFullYear()}/${now.getMonth()}/${now.getDate()}:${now.getHours()}:${now.getMinutes()}`
110  
111      const file = new AttachmentBuilder('./dist/utils/configs.json')
112          .setName('configs.json')
113          .setDescription(`From ${date}`);
114  
115      const channel = await client.channels.fetch(process.env.dumpChannel)?.catch(log4js.trace) as TextChannel
116      if (!channel) return
117  
118      channel.send({
119          content: `✅ | Dump config\nConfig file from ${date}`,
120          files: [file]
121      }).catch(log4js.trace)
122  }
123  export const setDumpClock = (client: Client) => {
124      const midnight = new Date(new Date().setHours(0, 0, 0, 0) + 86400000)
125      const diff = midnight.getTime() - Date.now()
126  
127      setTimeout(() => {
128          autoDump(client)
129  
130          setInterval(() => {
131              autoDump(client)
132          }, 86400000)
133      }, diff)
134  
135  }
136  export const getRandomStation = () => {
137      const keys = Object.keys(stations);
138      if (keys.length === 0) return null;
139      
140      const randomKey = keys[Math.floor(Math.random() * keys.length)];
141      return stations[randomKey];
142  }
143  export const convertTimestampToSeconds = (timestamp: string) => {
144      const parts = timestamp.split(':');
145      const integers = parts.map(x => parseInt(x))
146  
147      if (parts.length === 3) {
148          return integers[0] * 3600 + integers[1] * 60 + integers[2];
149      }
150      if (parts.length === 2) {
151          return integers[0] * 60 + integers[1];
152      }
153      if (parts.length === 1) {
154          return integers[0];
155      }
156  }
157  export const convertSecondsToTimestamp = (seconds: number) => {
158      const hours = Math.floor(seconds / 3600);
159      seconds %= 3600;
160      const minutes = Math.floor(seconds / 60);
161      seconds %= 60;
162  
163      const parts: string[] = [];
164      if (hours > 0) parts.push(hours.toString().padStart(2, '0'));
165      parts.push(minutes.toString().padStart(2, '0'));
166      parts.push(seconds.toString().padStart(2, '0'));
167  
168      return parts.join(':');
169  }
170  export const resolveName = (station: stationType<false>) => `${station.authors.join(' x ')} - ${station.title} ${station.beats}`.trim();
171  export const buildLocalizations = <Key extends keyof localizationsType<'commands'>>(command: Key): localizationBuilder<Key> => {
172      const langs = new Langs();
173      return langs.buildLocalizations(command);
174  };