| 1939 | 1965 | } |
| 1940 | 1966 | } |
| 1941 | 1967 | |
| 1968 | +/** |
| 1969 | + * |
| 1970 | + * @param {{title?: string, severity?: string, timeOut?: string, extendedTimeOut?: string, preventDuplicates?: string, awaitDismissal?: string}} args - named arguments from the slash command |
| 1971 | + * @param {string} value - The string to echo (unnamed argument from the slash command) |
| 1972 | + * @returns {Promise<string>} The text that was echoed |
| 1973 | + */ |
| 1942 | 1974 | async function echoCallback(args, value) { |
| 1943 | 1975 | // Note: We don't need to sanitize input, as toastr is set up by default to escape HTML via toastr options |
| 1944 | 1976 | if (value === '') { |
| 1945 | 1977 | console.warn('WARN: No argument provided for /echo command'); |
| 1946 | 1978 | return ''; |
| 1979 | + } |
| 1980 | + |
| 1981 | + if (args.severity && !['error', 'warning', 'success', 'info'].includes(args.severity)) { |
| 1982 | + toastr.warning(`Invalid severity provided for /echo command: ${args.severity}`); |
| 1983 | + args.severity = null; |
| 1947 | 1984 | } |
| 1948 | | - const title = args?.title !== undefined && typeof args?.title === 'string' ? args.title : undefined; |
| 1985 | + |
| 1949 | | - const severity = args?.severity !== undefined && typeof args?.severity === 'string' ? args.severity : 'info'; |
| 1986 | + const title = args.title ? args.title : undefined; |
| 1987 | + const severity = args.severity ? args.severity : 'info'; |
| 1988 | + |
| 1989 | + /** @type {ToastrOptions} */ |
| 1990 | + const options = {}; |
| 1991 | + if (args.timeOut && !isNaN(parseInt(args.timeOut))) options.timeOut = parseInt(args.timeOut); |
| 1992 | + if (args.extendedTimeOut && !isNaN(parseInt(args.extendedTimeOut))) options.extendedTimeOut = parseInt(args.extendedTimeOut); |
| 1993 | + if (isTrueBoolean(args.preventDuplicates)) options.preventDuplicates = true; |
| 1994 | + |
| 1995 | + // Prepare possible await handling |
| 1996 | + let awaitDismissal = isTrueBoolean(args.awaitDismissal); |
| 1997 | + let resolveToastDismissal; |
| 1998 | + |
| 1999 | + if (awaitDismissal) { |
| 2000 | + options.onHidden = () => resolveToastDismissal(value); |
| 2001 | + } |
| 2002 | + |
| 1950 | 2003 | switch (severity) { |
| 1951 | 2004 | case 'error': |
| 1952 | 2005 | toastr.error(value, title, options); |
| 1953 | 2006 | break; |
| 1954 | 2007 | case 'warning': |
| 1955 | 2008 | toastr.warning(value, title, options); |
| 1956 | 2009 | break; |
| 1957 | 2010 | case 'success': |
| 1958 | 2011 | toastr.success(value, title, options); |
| 1959 | 2012 | break; |
| 1960 | 2013 | case 'info': |
| 1961 | 2014 | default: |
| 1962 | 2015 | toastr.info(value, title, options); |
| 1963 | 2016 | break; |
| 1964 | 2017 | } |
| 2018 | + |
| 2019 | + if (awaitDismissal) { |
| 2020 | + return new Promise((resolve) => { |
| 2021 | + resolveToastDismissal = resolve; |
| 2022 | + }); |
| 2023 | + } else { |
| 1965 | 2024 | return value; |
| 1966 | 2025 | } |
| 2026 | +} |
| 2027 | + |
| 1967 | 2028 | |
| 1968 | 2029 | async function addSwipeCallback(_, arg) { |
| 1969 | 2030 | const lastMessage = chat[chat.length - 1]; |