Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 9 additions & 42 deletions packages/botonic-plugin-flow-builder/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
type HtSmartIntentNode,
} from './content-fields/hubtype-fields'
import { type FlowBuilderApiOptions, ProcessEnvNodeEnvs } from './types'
import { FlowLocale } from './utils/flow-locale'

export class FlowBuilderApi {
url: string
Expand Down Expand Up @@ -310,47 +311,13 @@ export class FlowBuilderApi {
}

getResolvedLocale(): string {
const systemLocale = this.request.getSystemLocale()

const locale = this.resolveAsLocale(systemLocale)
if (locale) {
return locale
}

const language = this.resolveAsLanguage(systemLocale)
if (language) {
this.request.setSystemLocale(language)
return language
}

const defaultLocale = this.resolveAsDefaultLocale()
this.request.setSystemLocale(defaultLocale)
return defaultLocale
}

private resolveAsLocale(locale: string): string | undefined {
if (this.flow.locales.find(flowLocale => flowLocale === locale)) {
return locale
}
return undefined
}

private resolveAsLanguage(locale?: string): string | undefined {
const language = locale?.split('-')[0]
if (
language &&
this.flow.locales.find(flowLocale => flowLocale === language)
) {
console.log(`locale: ${locale} has been resolved as ${language}`)
return language
}
return undefined
}

private resolveAsDefaultLocale(): string {
console.log(
`Resolve locale with default locale: ${this.flow.default_locale_code}`
)
return this.flow.default_locale_code || 'en'
const flowLocales = this.flow.locales
const defaultLocaleCode = this.flow.default_locale_code

return new FlowLocale(
this.request,
flowLocales,
defaultLocaleCode
).resolve()
}
}
83 changes: 83 additions & 0 deletions packages/botonic-plugin-flow-builder/src/utils/flow-locale.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import type { BotContext } from '@botonic/core'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i found interesting this proposal to make it more readable (as this is a very important point from now on):

import type { BotContext } from '@botonic/core'

export class FlowLocale {
  constructor(
    private readonly botContext: BotContext,
    private readonly flowLocales: string[],
    private readonly defaultLocaleCode: string
  ) {}

  resolve(): string {
    const priorityLocale = this.getPriorityLocale()

    if (priorityLocale) {
      const exactMatch = this.matchExactLocale(priorityLocale)
      if (exactMatch) return this.applyLocale(exactMatch)

      const languageMatch = this.matchLanguage(priorityLocale)
      if (languageMatch) return this.applyLocale(languageMatch)
    }

    return this.applyLocale(this.getDefaultLocale())
  }

  /**
   * Rules:
   * - If user and system languages differ, user locale takes priority.
   * - If both share the same language, the more specific locale wins.
   * - If both have the same specificity, user locale wins.
   */
  private getPriorityLocale(): string | undefined {
    const userLocale = this.botContext.getUserLocale()
    const systemLocale = this.botContext.getSystemLocale()

    if (!userLocale || !systemLocale) return undefined

    const userLanguage = this.getLanguage(userLocale)
    const systemLanguage = this.getLanguage(systemLocale)

    if (userLanguage !== systemLanguage) return userLocale

    const userIsSpecific = this.isSpecificLocale(userLocale)
    const systemIsSpecific = this.isSpecificLocale(systemLocale)

    if (userIsSpecific && !systemIsSpecific) return userLocale
    if (!userIsSpecific && systemIsSpecific) return systemLocale

    return userLocale
  }

  private matchExactLocale(locale: string): string | undefined {
    return this.flowLocales.includes(locale) ? locale : undefined
  }

  private matchLanguage(locale: string): string | undefined {
    const language = this.getLanguage(locale)
    return this.flowLocales.includes(language) ? language : undefined
  }

  private getDefaultLocale(): string {
    return this.defaultLocaleCode || 'en'
  }

  private applyLocale(locale: string): string {
    this.botContext.setSystemLocale(locale)
    this.botContext.session.user.system_locale_updated = true
    return locale
  }

  private getLanguage(locale: string): string {
    return locale.split('-')[0]
  }

  private isSpecificLocale(locale: string): boolean {
    return locale.includes('-')
  }
}


export class FlowLocale {
constructor(
private botContext: BotContext,
private flowLocales: string[],
private defaultLocaleCode: string
) {}

resolve(): string {
const resolvedUserLocale = this.resolveAsUserLocale()
if (resolvedUserLocale) {
return resolvedUserLocale
}

const resolvedSystemLocale = this.resolveAsSystemLocale()
if (resolvedSystemLocale) {
return resolvedSystemLocale
}

const defaultLocale = this.resolveAsDefaultLocale()
this.botContext.setSystemLocale(defaultLocale)
return defaultLocale
}

private resolveAsUserLocale(): string | undefined {
const userLocale = this.botContext.session.user.locale

const resolvedUserLocale = this.resolveAsLocale(userLocale)
if (resolvedUserLocale) {
this.botContext.setSystemLocale(resolvedUserLocale)
return resolvedUserLocale
}

const resolvedUserLanguage = this.resolveAsLanguage(userLocale)
if (resolvedUserLanguage) {
this.botContext.setSystemLocale(resolvedUserLanguage)
return resolvedUserLanguage
}

return undefined
}

private resolveAsSystemLocale(): string | undefined {
const systemLocale = this.botContext.getSystemLocale()

const locale = this.resolveAsLocale(systemLocale)
if (locale) {
return locale
}

const language = this.resolveAsLanguage(systemLocale)
if (language) {
this.botContext.setSystemLocale(language)
return language
}
return undefined
}

private resolveAsLocale(locale: string): string | undefined {
if (this.flowLocales.find(flowLocale => flowLocale === locale)) {
return locale
}
return undefined
}

private resolveAsLanguage(locale?: string): string | undefined {
const language = locale?.split('-')[0]
if (
language &&
this.flowLocales.find(flowLocale => flowLocale === language)
) {
// console.log(`locale: ${locale} has been resolved as ${language}`)
return language
}
return undefined
}

private resolveAsDefaultLocale(): string {
// console.log(`Resolve locale with default locale: ${this.defaultLocaleCode}`)
return this.defaultLocaleCode || 'en'
}
}
Loading
Loading