constants.ts raw

   1  import { kinds } from 'nostr-tools'
   2  
   3  export const DEPLOYMENT = {
   4    loginMethods: (import.meta.env.VITE_LOGIN_METHODS || 'nsec,nip07,bunker')
   5      .split(',')
   6      .map((s: string) => s.trim()),
   7    defaultRelay: import.meta.env.VITE_DEFAULT_RELAY || ''
   8  } as const
   9  
  10  export const SMESH_API_BASE_URL = 'https://api.smesh.social'
  11  
  12  export const RECOMMENDED_BLOSSOM_SERVERS = [
  13    'https://blossom.band/',
  14    'https://blossom.primal.net/',
  15    'https://nostr.media/'
  16  ]
  17  
  18  export const StorageKey = {
  19    VERSION: 'version',
  20    THEME_SETTING: 'themeSetting',
  21    RELAY_SETS: 'relaySets',
  22    ACCOUNTS: 'accounts',
  23    CURRENT_ACCOUNT: 'currentAccount',
  24    ADD_CLIENT_TAG: 'addClientTag',
  25    NOTE_LIST_MODE: 'noteListMode',
  26    NOTIFICATION_TYPE: 'notificationType',
  27    DEFAULT_ZAP_SATS: 'defaultZapSats',
  28    DEFAULT_ZAP_COMMENT: 'defaultZapComment',
  29    QUICK_ZAP: 'quickZap',
  30    LAST_READ_NOTIFICATION_TIME_MAP: 'lastReadNotificationTimeMap',
  31    ACCOUNT_FEED_INFO_MAP: 'accountFeedInfoMap',
  32    AUTOPLAY: 'autoplay',
  33    HIDE_UNTRUSTED_INTERACTIONS: 'hideUntrustedInteractions',
  34    HIDE_UNTRUSTED_NOTIFICATIONS: 'hideUntrustedNotifications',
  35    TRANSLATION_SERVICE_CONFIG_MAP: 'translationServiceConfigMap',
  36    MEDIA_UPLOAD_SERVICE_CONFIG_MAP: 'mediaUploadServiceConfigMap',
  37    HIDE_UNTRUSTED_NOTES: 'hideUntrustedNotes',
  38    DISMISSED_TOO_MANY_RELAYS_ALERT: 'dismissedTooManyRelaysAlert',
  39    SHOW_KINDS: 'showKinds',
  40    SHOW_KINDS_VERSION: 'showKindsVersion',
  41    HIDE_CONTENT_MENTIONING_MUTED_USERS: 'hideContentMentioningMutedUsers',
  42    NOTIFICATION_LIST_STYLE: 'notificationListStyle',
  43    MEDIA_AUTO_LOAD_POLICY: 'mediaAutoLoadPolicy',
  44    SHOWN_CREATE_WALLET_GUIDE_TOAST_PUBKEYS: 'shownCreateWalletGuideToastPubkeys',
  45    SIDEBAR_COLLAPSE: 'sidebarCollapse',
  46    PRIMARY_COLOR: 'primaryColor',
  47    ENABLE_SINGLE_COLUMN_LAYOUT: 'enableSingleColumnLayout',
  48    FALLBACK_RELAY_COUNT: 'fallbackRelayCount',
  49    FAVICON_URL_TEMPLATE: 'faviconUrlTemplate',
  50    FILTER_OUT_ONION_RELAYS: 'filterOutOnionRelays',
  51    QUICK_REACTION: 'quickReaction',
  52    QUICK_REACTION_EMOJI: 'quickReactionEmoji',
  53    NSFW_DISPLAY_POLICY: 'nsfwDisplayPolicy',
  54    PREFER_NIP44: 'preferNip44',
  55    DM_CONVERSATION_FILTER: 'dmConversationFilter',
  56    DM_ENCRYPTION_PREFERENCES: 'dmEncryptionPreferences',
  57    DM_LAST_SEEN_TIMESTAMP: 'dmLastSeenTimestamp',
  58    GRAPH_QUERIES_ENABLED: 'graphQueriesEnabled',
  59    SOCIAL_GRAPH_PROXIMITY: 'socialGraphProximity',
  60    SOCIAL_GRAPH_INCLUDE_MODE: 'socialGraphIncludeMode',
  61    NRC_ONLY_CONFIG_SYNC: 'nrcOnlyConfigSync',
  62    AUTO_INSERT_NEW_NOTES: 'autoInsertNewNotes',
  63    VERBOSE_LOGGING: 'verboseLogging',
  64    ENABLE_MARKDOWN: 'enableMarkdown',
  65    SEARCH_RELAYS: 'searchRelays',
  66    LLM_CONFIG_MAP: 'llmConfigMap',
  67    OUTBOX_MODE: 'outboxMode',
  68    DEFAULT_SHOW_NSFW: 'defaultShowNsfw', // deprecated
  69    PINNED_PUBKEYS: 'pinnedPubkeys', // deprecated
  70    MEDIA_UPLOAD_SERVICE: 'mediaUploadService', // deprecated
  71    HIDE_UNTRUSTED_EVENTS: 'hideUntrustedEvents', // deprecated
  72    ACCOUNT_RELAY_LIST_EVENT_MAP: 'accountRelayListEventMap', // deprecated
  73    ACCOUNT_FOLLOW_LIST_EVENT_MAP: 'accountFollowListEventMap', // deprecated
  74    ACCOUNT_MUTE_LIST_EVENT_MAP: 'accountMuteListEventMap', // deprecated
  75    ACCOUNT_MUTE_DECRYPTED_TAGS_MAP: 'accountMuteDecryptedTagsMap', // deprecated
  76    ACCOUNT_PROFILE_EVENT_MAP: 'accountProfileEventMap', // deprecated
  77    ACTIVE_RELAY_SET_ID: 'activeRelaySetId', // deprecated
  78    FEED_TYPE: 'feedType' // deprecated
  79  }
  80  
  81  export const ApplicationDataKey = {
  82    NOTIFICATIONS_SEEN_AT: 'seen_notifications_at',
  83    SETTINGS: 'smesh_settings',
  84    DM_DELETED_MESSAGES: 'dm_deleted_messages',
  85    // Relay hint for DMs - contains bech32-encoded relays (nrelay1...) that smesh clients should check first
  86    DM_RELAY_HINT: 'smesh_dm_relays'
  87  }
  88  
  89  /**
  90   * Recommended search relays that users can opt into.
  91   * These are NOT used by default - search is opt-in to protect privacy.
  92   * Users must explicitly configure search relays or accept these recommendations.
  93   */
  94  export const RECOMMENDED_SEARCH_RELAYS = [
  95    'wss://search.nos.today/',
  96    'wss://relay.ditto.pub/',
  97    'wss://relay.nostrcheck.me/',
  98    'wss://relay.nostr.band/'
  99  ]
 100  
 101  export const GROUP_METADATA_EVENT_KIND = 39000
 102  
 103  export const ExtendedKind = {
 104    SEAL: 13,
 105    PRIVATE_DM: 14,
 106    EXTERNAL_CONTENT_REACTION: 17,
 107    PICTURE: 20,
 108    VIDEO: 21,
 109    SHORT_VIDEO: 22,
 110    POLL: 1068,
 111    POLL_RESPONSE: 1018,
 112    COMMENT: 1111,
 113    VOICE: 1222,
 114    GIFT_WRAP: 1059,
 115    VOICE_COMMENT: 1244,
 116    PINNED_USERS: 10010,
 117    FAVORITE_RELAYS: 10012,
 118    BLOSSOM_SERVER_LIST: 10063,
 119    FOLLOW_PACK: 39089,
 120    RELAY_REVIEW: 31987,
 121    GROUP_METADATA: 39000,
 122    ADDRESSABLE_NORMAL_VIDEO: 34235,
 123    ADDRESSABLE_SHORT_VIDEO: 34236
 124  }
 125  
 126  export const ALLOWED_FILTER_KINDS = [
 127    kinds.ShortTextNote,
 128    kinds.Repost,
 129    kinds.GenericRepost,
 130    ExtendedKind.PICTURE,
 131    ExtendedKind.VIDEO,
 132    ExtendedKind.SHORT_VIDEO,
 133    ExtendedKind.POLL,
 134    ExtendedKind.COMMENT,
 135    ExtendedKind.VOICE,
 136    ExtendedKind.VOICE_COMMENT,
 137    kinds.Highlights,
 138    kinds.LongFormArticle,
 139    ExtendedKind.ADDRESSABLE_NORMAL_VIDEO,
 140    ExtendedKind.ADDRESSABLE_SHORT_VIDEO
 141  ]
 142  
 143  export const SUPPORTED_KINDS = [
 144    ...ALLOWED_FILTER_KINDS,
 145    ExtendedKind.RELAY_REVIEW,
 146    kinds.Emojisets,
 147    ExtendedKind.FOLLOW_PACK
 148  ]
 149  
 150  export const URL_REGEX =
 151    /https?:\/\/[\w\p{L}\p{N}\p{M}&.\-/?=#@%+_:!~*]+[^\s.,;:'")\]}!?,。;:"'!?】)]/giu
 152  export const WS_URL_REGEX =
 153    /wss?:\/\/[\w\p{L}\p{N}\p{M}&.\-/?=#@%+_:!~*]+[^\s.,;:'")\]}!?,。;:"'!?】)]/giu
 154  export const EMAIL_REGEX = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
 155  export const EMOJI_SHORT_CODE_REGEX = /:[a-zA-Z0-9_-]+:/g
 156  export const EMBEDDED_EVENT_REGEX = /nostr:(note1[a-z0-9]{58}|nevent1[a-z0-9]+|naddr1[a-z0-9]+)/g
 157  export const EMBEDDED_MENTION_REGEX = /nostr:(npub1[a-z0-9]{58}|nprofile1[a-z0-9]+)/g
 158  export const HASHTAG_REGEX = /#[\p{L}\p{N}\p{M}_]+/gu
 159  export const LN_INVOICE_REGEX = /(ln(?:bc|tb|bcrt))([0-9]+[munp]?)?1([02-9ac-hj-np-z]+)/g
 160  export const EMOJI_REGEX =
 161    /[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]|[\u{1F900}-\u{1F9FF}]|[\u{1FA70}-\u{1FAFF}]|[\u{1F004}]|[\u{1F0CF}]|[\u{1F18E}]|[\u{3030}]|[\u{2B50}]|[\u{2B55}]|[\u{2934}-\u{2935}]|[\u{2B05}-\u{2B07}]|[\u{2B1B}-\u{2B1C}]|[\u{3297}]|[\u{3299}]|[\u{303D}]|[\u{00A9}]|[\u{00AE}]|[\u{2122}]|[\u{23E9}-\u{23EF}]|[\u{23F0}]|[\u{23F3}]|[\u{FE00}-\u{FE0F}]|[\u{200D}]/gu
 162  export const YOUTUBE_URL_REGEX =
 163    /https?:\/\/(?:(?:www|m)\.)?(?:youtube\.com\/(?:watch\?[^#\s]*|embed\/[\w-]+|shorts\/[\w-]+|live\/[\w-]+)|youtu\.be\/[\w-]+)(?:\?[^#\s]*)?(?:#[^\s]*)?/gi
 164  export const X_URL_REGEX =
 165    /https?:\/\/(?:www\.)?(twitter\.com|x\.com)\/(?:#!\/)?(\w+)\/status(?:es)?\/(\d+)(?:[?#].*)?/gi
 166  
 167  export const SMESH_PUBKEY = '4c800257a588a82849d049817c2bdaad984b25a45ad9f6dad66e47d3b47e3b2f'
 168  
 169  export const NIP_96_SERVICE = [
 170    'https://mockingyou.com',
 171    'https://nostpic.com',
 172    'https://nostr.build', // default
 173    'https://nostrcheck.me',
 174    'https://nostrmedia.com',
 175    'https://files.sovbit.host'
 176  ]
 177  export const DEFAULT_NIP_96_SERVICE = 'https://nostr.build'
 178  
 179  export const DEFAULT_FAVICON_URL_TEMPLATE = 'https://{hostname}/favicon.ico'
 180  
 181  export const POLL_TYPE = {
 182    MULTIPLE_CHOICE: 'multiplechoice',
 183    SINGLE_CHOICE: 'singlechoice'
 184  } as const
 185  
 186  export const NOTIFICATION_LIST_STYLE = {
 187    COMPACT: 'compact',
 188    DETAILED: 'detailed'
 189  } as const
 190  
 191  export const MEDIA_AUTO_LOAD_POLICY = {
 192    ALWAYS: 'always',
 193    WIFI_ONLY: 'wifi-only',
 194    NEVER: 'never'
 195  } as const
 196  
 197  export const NSFW_DISPLAY_POLICY = {
 198    HIDE: 'hide',
 199    HIDE_CONTENT: 'hide_content',
 200    SHOW: 'show'
 201  } as const
 202  
 203  export const MAX_PINNED_NOTES = 10
 204  
 205  export const PRIMARY_COLORS = {
 206    DEFAULT: {
 207      name: 'Default',
 208      light: {
 209        primary: '38 92% 50%',
 210        'primary-hover': '38 92% 60%',
 211        'primary-foreground': '0 0% 10%',
 212        ring: '38 92% 50%'
 213      },
 214      dark: {
 215        primary: '38 92% 50%',
 216        'primary-hover': '38 92% 60%',
 217        'primary-foreground': '240 5.9% 10%',
 218        ring: '38 92% 50%'
 219      }
 220    },
 221    RED: {
 222      name: 'Red',
 223      light: {
 224        primary: '0 65% 55%',
 225        'primary-hover': '0 65% 65%',
 226        'primary-foreground': '0 0% 98%',
 227        ring: '0 65% 55%'
 228      },
 229      dark: {
 230        primary: '0 65% 55%',
 231        'primary-hover': '0 65% 65%',
 232        'primary-foreground': '240 5.9% 10%',
 233        ring: '0 65% 55%'
 234      }
 235    },
 236    ORANGE: {
 237      name: 'Orange',
 238      light: {
 239        primary: '30 100% 50%',
 240        'primary-hover': '30 100% 60%',
 241        'primary-foreground': '0 0% 98%',
 242        ring: '30 100% 50%'
 243      },
 244      dark: {
 245        primary: '30 100% 50%',
 246        'primary-hover': '30 100% 60%',
 247        'primary-foreground': '240 5.9% 10%',
 248        ring: '30 100% 50%'
 249      }
 250    },
 251    AMBER: {
 252      name: 'Amber',
 253      light: {
 254        primary: '42 100% 50%',
 255        'primary-hover': '42 100% 60%',
 256        'primary-foreground': '0 0% 98%',
 257        ring: '42 100% 50%'
 258      },
 259      dark: {
 260        primary: '42 100% 50%',
 261        'primary-hover': '42 100% 60%',
 262        'primary-foreground': '240 5.9% 10%',
 263        ring: '42 100% 50%'
 264      }
 265    },
 266    YELLOW: {
 267      name: 'Yellow',
 268      light: {
 269        primary: '54 100% 50%',
 270        'primary-hover': '54 100% 60%',
 271        'primary-foreground': '0 0% 10%',
 272        ring: '54 100% 50%'
 273      },
 274      dark: {
 275        primary: '54 100% 50%',
 276        'primary-hover': '54 100% 60%',
 277        'primary-foreground': '240 5.9% 10%',
 278        ring: '54 100% 50%'
 279      }
 280    },
 281    LIME: {
 282      name: 'Lime',
 283      light: {
 284        primary: '90 60% 50%',
 285        'primary-hover': '90 60% 60%',
 286        'primary-foreground': '0 0% 98%',
 287        ring: '90 60% 50%'
 288      },
 289      dark: {
 290        primary: '90 60% 50%',
 291        'primary-hover': '90 60% 60%',
 292        'primary-foreground': '240 5.9% 10%',
 293        ring: '90 60% 50%'
 294      }
 295    },
 296    GREEN: {
 297      name: 'Green',
 298      light: {
 299        primary: '140 60% 40%',
 300        'primary-hover': '140 60% 50%',
 301        'primary-foreground': '0 0% 98%',
 302        ring: '140 60% 40%'
 303      },
 304      dark: {
 305        primary: '140 60% 40%',
 306        'primary-hover': '140 60% 50%',
 307        'primary-foreground': '240 5.9% 10%',
 308        ring: '140 60% 40%'
 309      }
 310    },
 311    EMERALD: {
 312      name: 'Emerald',
 313      light: {
 314        primary: '160 70% 40%',
 315        'primary-hover': '160 70% 50%',
 316        'primary-foreground': '0 0% 98%',
 317        ring: '160 70% 40%'
 318      },
 319      dark: {
 320        primary: '160 70% 40%',
 321        'primary-hover': '160 70% 50%',
 322        'primary-foreground': '240 5.9% 10%',
 323        ring: '160 70% 40%'
 324      }
 325    },
 326    TEAL: {
 327      name: 'Teal',
 328      light: {
 329        primary: '180 70% 40%',
 330        'primary-hover': '180 70% 50%',
 331        'primary-foreground': '0 0% 98%',
 332        ring: '180 70% 40%'
 333      },
 334      dark: {
 335        primary: '180 70% 40%',
 336        'primary-hover': '180 70% 50%',
 337        'primary-foreground': '240 5.9% 10%',
 338        ring: '180 70% 40%'
 339      }
 340    },
 341    CYAN: {
 342      name: 'Cyan',
 343      light: {
 344        primary: '200 70% 40%',
 345        'primary-hover': '200 70% 50%',
 346        'primary-foreground': '0 0% 98%',
 347        ring: '200 70% 40%'
 348      },
 349      dark: {
 350        primary: '200 70% 40%',
 351        'primary-hover': '200 70% 50%',
 352        'primary-foreground': '240 5.9% 10%',
 353        ring: '200 70% 40%'
 354      }
 355    },
 356    SKY: {
 357      name: 'Sky',
 358      light: {
 359        primary: '210 70% 50%',
 360        'primary-hover': '210 70% 60%',
 361        'primary-foreground': '0 0% 98%',
 362        ring: '210 70% 50%'
 363      },
 364      dark: {
 365        primary: '210 70% 50%',
 366        'primary-hover': '210 70% 60%',
 367        'primary-foreground': '240 5.9% 10%',
 368        ring: '210 70% 50%'
 369      }
 370    },
 371    BLUE: {
 372      name: 'Blue',
 373      light: {
 374        primary: '220 80% 50%',
 375        'primary-hover': '220 80% 60%',
 376        'primary-foreground': '0 0% 98%',
 377        ring: '220 80% 50%'
 378      },
 379      dark: {
 380        primary: '220 80% 50%',
 381        'primary-hover': '220 80% 60%',
 382        'primary-foreground': '240 5.9% 10%',
 383        ring: '220 80% 50%'
 384      }
 385    },
 386    INDIGO: {
 387      name: 'Indigo',
 388      light: {
 389        primary: '230 80% 50%',
 390        'primary-hover': '230 80% 60%',
 391        'primary-foreground': '0 0% 98%',
 392        ring: '230 80% 50%'
 393      },
 394      dark: {
 395        primary: '230 80% 50%',
 396        'primary-hover': '230 80% 60%',
 397        'primary-foreground': '240 5.9% 10%',
 398        ring: '230 80% 50%'
 399      }
 400    },
 401    VIOLET: {
 402      name: 'Violet',
 403      light: {
 404        primary: '250 80% 50%',
 405        'primary-hover': '250 80% 60%',
 406        'primary-foreground': '0 0% 98%',
 407        ring: '250 80% 50%'
 408      },
 409      dark: {
 410        primary: '250 80% 50%',
 411        'primary-hover': '250 80% 60%',
 412        'primary-foreground': '240 5.9% 10%',
 413        ring: '250 80% 50%'
 414      }
 415    },
 416    PURPLE: {
 417      name: 'Purple',
 418      light: {
 419        primary: '280 80% 50%',
 420        'primary-hover': '280 80% 60%',
 421        'primary-foreground': '0 0% 98%',
 422        ring: '280 80% 50%'
 423      },
 424      dark: {
 425        primary: '280 80% 50%',
 426        'primary-hover': '280 80% 60%',
 427        'primary-foreground': '240 5.9% 10%',
 428        ring: '280 80% 50%'
 429      }
 430    },
 431    FUCHSIA: {
 432      name: 'Fuchsia',
 433      light: {
 434        primary: '310 80% 50%',
 435        'primary-hover': '310 80% 60%',
 436        'primary-foreground': '0 0% 98%',
 437        ring: '310 80% 50%'
 438      },
 439      dark: {
 440        primary: '310 80% 50%',
 441        'primary-hover': '310 80% 60%',
 442        'primary-foreground': '240 5.9% 10%',
 443        ring: '310 80% 50%'
 444      }
 445    },
 446    PINK: {
 447      name: 'Pink',
 448      light: {
 449        primary: '330 80% 60%',
 450        'primary-hover': '330 80% 70%',
 451        'primary-foreground': '0 0% 10%',
 452        ring: '330 80% 60%'
 453      },
 454      dark: {
 455        primary: '330 80% 60%',
 456        'primary-hover': '330 80% 70%',
 457        'primary-foreground': '240 5.9% 10%',
 458        ring: '330 80% 60%'
 459      }
 460    },
 461    ROSE: {
 462      name: 'Rose',
 463      light: {
 464        primary: '350 80% 60%',
 465        'primary-hover': '350 80% 70%',
 466        'primary-foreground': '0 0% 10%',
 467        ring: '350 80% 60%'
 468      },
 469      dark: {
 470        primary: '350 80% 60%',
 471        'primary-hover': '350 80% 70%',
 472        'primary-foreground': '240 5.9% 10%',
 473        ring: '350 80% 60%'
 474      }
 475    }
 476  } as const
 477  export type TPrimaryColor = keyof typeof PRIMARY_COLORS
 478  
 479  export const LONG_PRESS_THRESHOLD = 400
 480