11import { cmdLn , t } from "@dicelette/localization" ;
2- import type { Translation } from "@dicelette/types" ;
2+ import {
3+ DEFAULT_TEMPLATE ,
4+ LinksVariables ,
5+ type TemplateResult ,
6+ type Translation ,
7+ } from "@dicelette/types" ;
38import type { EClient } from "client" ;
49import * as Djs from "discord.js" ;
510import { getLangAndConfig } from "../utils" ;
611
12+ type Results = {
13+ info : string ;
14+ dice : string ;
15+ } ;
16+
17+ type Variables = {
18+ rolls : Results [ ] ;
19+ stats ?: string ;
20+ link : string ;
21+ } ;
22+
723export const contextMenus = [
824 new Djs . ContextMenuCommandBuilder ( )
925 . setName ( t ( "copyRollResult.name" ) )
@@ -16,16 +32,21 @@ export async function commandMenu(
1632 client : EClient
1733) {
1834 const { ul } = getLangAndConfig ( client , interaction ) ;
35+
1936 if ( interaction . targetMessage . author . id !== client . user ?. id ) {
2037 await interaction . reply ( {
2138 content : ul ( "copyRollResult.error.notBot" ) ,
39+ flags : Djs . MessageFlags . Ephemeral ,
2240 } ) ;
2341 return ;
2442 }
43+
44+ const template = getTemplate ( client , interaction ) ;
45+
2546 const message = interaction . targetMessage . content ;
2647 const messageUrl = interaction . targetMessage . url ;
2748
28- const link = await finalLink ( message , messageUrl , ul ) ;
49+ const link = finalLink ( template , message , messageUrl ) ;
2950 if ( ! link ) {
3051 await interaction . reply ( {
3152 content : ul ( "copyRollResult.error.noResult" ) ,
@@ -37,48 +58,158 @@ export async function commandMenu(
3758 content : `\`\`${ link } \`\`` ,
3859 flags : Djs . MessageFlags . Ephemeral ,
3960 } ) ;
61+ }
4062
41- /**
42- * Not needed anymore as mobile support copy in codeblocks
43- await interaction.followUp({
44- content: `${link}`,
45- flags: Djs.MessageFlags.Ephemeral,
63+ function replaceAllTokens ( text : string , map : Record < string , string > ) {
64+ return Object . entries ( map ) . reduce ( ( acc , [ k , v ] ) => acc . replaceAll ( k , v ) , text ) ;
65+ }
66+
67+ export function finalLink (
68+ template : TemplateResult | undefined ,
69+ message : string ,
70+ messageUrl : string
71+ ) {
72+ const variables = getVariablesTemplate ( message , messageUrl ) ;
73+ if ( ! variables ) return undefined ;
74+ template = template ?? DEFAULT_TEMPLATE ;
75+
76+ const resultsText = createResultFromTemplate ( template , variables ) ;
77+
78+ let finalText = replaceAllTokens ( template ! . final , {
79+ [ LinksVariables . LINK ] : variables . link ,
80+ [ LinksVariables . RESULTS ] : resultsText ,
81+ } ) ;
82+
83+ if ( variables . stats ) {
84+ const statText = getShortLong ( variables . stats ) ;
85+ const statFinal = replaceAllTokens ( template ! . format . name , {
86+ [ LinksVariables . NAME ] : statText . long ,
87+ [ LinksVariables . NAME_LONG ] : statText . long ,
88+ [ LinksVariables . NAME_SHORT ] : statText . short ,
89+ } ) ;
90+ finalText = replaceAllTokens ( finalText , {
91+ [ LinksVariables . NAME ] : statFinal ,
92+ [ LinksVariables . NAME_LONG ] : statFinal ,
93+ [ LinksVariables . NAME_SHORT ] : statFinal ,
94+ } ) ;
95+ } else {
96+ finalText = replaceAllTokens ( finalText , {
97+ [ LinksVariables . NAME ] : "" ,
98+ [ LinksVariables . NAME_LONG ] : "" ,
99+ [ LinksVariables . NAME_SHORT ] : "" ,
100+ } ) ;
101+ }
102+
103+ return finalText ;
104+ }
105+
106+ function createResultFromTemplate (
107+ template : TemplateResult | undefined ,
108+ variables : Variables
109+ ) {
110+ template = template ?? DEFAULT_TEMPLATE ;
111+ const fmt = template ! . format ;
112+
113+ const rollsText = variables . rolls . map ( ( { info, dice } ) => {
114+ const infoTrim = info . trim ( ) ;
115+ const diceTrim = dice . trim ( ) ;
116+
117+ const infoFinal = infoTrim
118+ ? ( ( ) => {
119+ const c = getShortLong ( infoTrim ) ;
120+ return replaceAllTokens ( fmt . info , {
121+ [ LinksVariables . INFO ] : c . long ,
122+ [ LinksVariables . INFO_LONG ] : c . long ,
123+ [ LinksVariables . INFO_SHORT ] : c . short ,
124+ } ) . trim ( ) ;
125+ } ) ( )
126+ : "" ;
127+
128+ const resultFinal = diceTrim
129+ ? fmt . dice . replace ( LinksVariables . DICE , diceTrim ) . trim ( )
130+ : "" ;
131+
132+ return template ! . results
133+ . replace ( LinksVariables . INFO , infoFinal )
134+ . replaceAll ( LinksVariables . INFO_LONG , infoFinal )
135+ . replaceAll ( LinksVariables . INFO_SHORT , infoFinal )
136+ . replace ( LinksVariables . DICE , resultFinal )
137+ . trim ( ) ;
46138 } ) ;
47- */
139+
140+ return rollsText . join ( template ! . joinResult ) ;
141+ }
142+
143+ function getShortLong ( text : string ) {
144+ text = text . replaceAll ( "**" , "" ) . trim ( ) ;
145+ const short =
146+ text . split ( " " ) . length > 1
147+ ? text
148+ . split ( " " )
149+ . map ( ( word ) => word . charAt ( 0 ) . toUpperCase ( ) )
150+ . join ( "" )
151+ : text ;
152+ return {
153+ /** Complet */
154+ long : text ,
155+ /** Initial only if word > 1, like Foo Bar = FB and Foo will be Foo*/
156+ short,
157+ } ;
48158}
49159
50- async function finalLink ( message : string , messageUrl : string , ul : Translation ) {
160+ function getVariablesTemplate ( message : string , messageUrl : string ) {
51161 const regexResultForRoll = / = ` (?< result > .* ) ` / gi;
52- const successFail = / ( { 2 } | _ _ ) (?< compare > .* ) — / gi;
162+ const successFail = / ( { 2 } | _ _ ) (?< info > .* ) — / gi;
53163
54164 const list = message . split ( "\n" ) ;
55- const res : string [ ] = [ ] ;
165+ const variables : Results [ ] = [ ] ;
56166 for ( const line of list ) {
57167 if ( ! line . match ( / ^ [ \s _ ] + / ) ) continue ;
58168 const match = regexResultForRoll . exec ( line ) ?. groups ?. result ;
59- const compare = successFail . exec ( line ) ?. groups ?. compare ;
60- if ( match && compare ) res . push ( ` ${ compare . trim ( ) } — \` ${ match . trim ( ) } \`` ) ;
61- else if ( match ) res . push ( `\` ${ match . trim ( ) } \`` ) ;
169+ const info = successFail . exec ( line ) ?. groups ?. info ;
170+ if ( match && info ) variables . push ( { dice : match . trim ( ) , info : info . trim ( ) } ) ;
171+ else if ( match ) variables . push ( { dice : match . trim ( ) , info : "" } ) ;
62172 }
63-
64- if ( res . length === 0 ) return undefined ;
173+ if ( variables . length === 0 ) return undefined ;
65174
66175 const statsReg = / \[ _ _ (?< stats > .* ) _ _ ] / gi;
67176 const stats = statsReg . exec ( message ) ?. groups ?. stats ;
68-
69177 const regexSavedDice =
70178 / - # ↪ (?< saved > h t t p s : \/ \/ d i s c o r d \. c o m \/ c h a n n e l s \/ \d + \/ \d + \/ \d + ) / gi;
71- let savedDice = regexSavedDice . exec ( message ) ?. groups ?. saved ;
72- const generateMessage = `[[${ stats ? `__${ stats } __${ ul ( "common.space" ) } : ` : "" } ${ res . join ( " ; " ) } ]]` ;
73- if ( ! savedDice ) savedDice = messageUrl ;
74- return `${ generateMessage } (<${ savedDice } >)` ;
179+ const savedDice = regexSavedDice . exec ( message ) ?. groups ?. saved ;
180+
181+ return {
182+ link : savedDice ?? messageUrl ,
183+ rolls : variables ,
184+ stats : stats ? stats : undefined ,
185+ } ;
186+ }
187+
188+ function getTemplate (
189+ client : EClient ,
190+ interaction : Djs . ButtonInteraction | Djs . MessageContextMenuCommandInteraction
191+ ) {
192+ const templateExportText = client . settings . get (
193+ interaction . guildId ! ,
194+ "createLinkTemplate"
195+ ) ;
196+ const userTemplate = client . userSettings . get (
197+ interaction . guildId ! ,
198+ interaction . user . id
199+ ) ?. createLinkTemplate ;
200+ return templateExportText ?? userTemplate ?? DEFAULT_TEMPLATE ;
75201}
76202
77- export async function mobileLink ( interaction : Djs . ButtonInteraction , ul : Translation ) {
203+ export async function mobileLink (
204+ interaction : Djs . ButtonInteraction ,
205+ ul : Translation ,
206+ client : EClient
207+ ) {
78208 const message = interaction . message . content ;
79209 const messageUrl = interaction . message . url ;
210+ const template = getTemplate ( client , interaction ) ;
80211 //check user mobile or desktop
81- const link = await finalLink ( message , messageUrl , ul ) ;
212+ const link = finalLink ( template , message , messageUrl ) ;
82213 if ( ! link ) {
83214 await interaction . reply ( {
84215 content : ul ( "copyRollResult.error.noResult" ) ,
@@ -92,10 +223,15 @@ export async function mobileLink(interaction: Djs.ButtonInteraction, ul: Transla
92223 } ) ;
93224}
94225
95- export async function desktopLink ( interaction : Djs . ButtonInteraction , ul : Translation ) {
226+ export async function desktopLink (
227+ interaction : Djs . ButtonInteraction ,
228+ ul : Translation ,
229+ client : EClient
230+ ) {
231+ const template = getTemplate ( client , interaction ) ;
96232 const message = interaction . message . content ;
97233 const messageUrl = interaction . message . url ;
98- const link = await finalLink ( message , messageUrl , ul ) ;
234+ const link = finalLink ( template , message , messageUrl ) ;
99235 if ( ! link ) {
100236 await interaction . reply ( {
101237 content : ul ( "copyRollResult.error.noResult" ) ,
0 commit comments