format (almost) everything remaining with prettier

This commit is contained in:
emma 2022-12-08 19:48:04 +00:00
parent 142f90c4cf
commit b07cf33a04
39 changed files with 1995 additions and 1812 deletions

View File

@ -1,5 +1,9 @@
{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-transform-runtime", "lodash", "@vue/babel-plugin-jsx"],
"plugins": [
"@babel/plugin-transform-runtime",
"lodash",
"@vue/babel-plugin-jsx"
],
"comments": false
}

View File

@ -11,14 +11,17 @@ var webpackConfig = require('./webpack.prod.conf')
console.log(
' Tip:\n' +
' Built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
' Built files are meant to be served over an HTTP server.\n' +
" Opening index.html over file:// won't work.\n"
)
var spinner = ora('building for production...')
spinner.start()
var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)
var assetsPath = path.join(
config.build.assetsRoot,
config.build.assetsSubDirectory
)
rm('-rf', assetsPath)
mkdir('-p', assetsPath)
cp('-R', 'static/*', assetsPath)
@ -26,11 +29,13 @@ cp('-R', 'static/*', assetsPath)
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n')
process.stdout.write(
stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n'
)
})

View File

@ -2,8 +2,7 @@ var semver = require('semver')
var chalk = require('chalk')
var packageConfig = require('../package.json')
var exec = function (cmd) {
return require('child_process')
.execSync(cmd).toString().trim()
return require('child_process').execSync(cmd).toString().trim()
}
var versionRequirements = [
@ -24,16 +23,23 @@ module.exports = function () {
for (var i = 0; i < versionRequirements.length; i++) {
var mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
warnings.push(
mod.name +
': ' +
chalk.red(mod.currentVersion) +
' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log(
chalk.yellow(
'To use this template, you must update following to modules:'
)
)
console.log()
for (var i = 0; i < warnings.length; i++) {
var warning = warnings[i]

View File

@ -6,9 +6,10 @@ var express = require('express')
var webpack = require('webpack')
var opn = require('opn')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = process.env.NODE_ENV === 'testing'
? require('./webpack.prod.conf')
: require('./webpack.dev.conf')
var webpackConfig =
process.env.NODE_ENV === 'testing'
? require('./webpack.prod.conf')
: require('./webpack.dev.conf')
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
@ -50,7 +51,10 @@ app.use(devMiddleware)
app.use(hotMiddleware)
// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
var staticPath = path.posix.join(
config.dev.assetsPublicPath,
config.dev.assetsSubDirectory
)
app.use(staticPath, express.static('./static'))
module.exports = app.listen(port, function (err) {

View File

@ -4,7 +4,8 @@ var sass = require('sass')
var MiniCssExtractPlugin = require('mini-css-extract-plugin')
exports.assetsPath = function (_path) {
var assetsSubDirectory = process.env.NODE_ENV === 'production'
var assetsSubDirectory =
process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
@ -13,7 +14,7 @@ exports.assetsPath = function (_path) {
exports.cssLoaders = function (options) {
options = options || {}
function generateLoaders (loaders) {
function generateLoaders(loaders) {
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
@ -27,11 +28,11 @@ exports.cssLoaders = function (options) {
return [
{
test: /\.(post)?css$/,
use: generateLoaders(['css-loader', 'postcss-loader']),
use: generateLoaders(['css-loader', 'postcss-loader'])
},
{
test: /\.less$/,
use: generateLoaders(['css-loader', 'postcss-loader', 'less-loader']),
use: generateLoaders(['css-loader', 'postcss-loader', 'less-loader'])
},
{
test: /\.sass$/,
@ -52,8 +53,8 @@ exports.cssLoaders = function (options) {
},
{
test: /\.styl(us)?$/,
use: generateLoaders(['css-loader', 'postcss-loader', 'stylus-loader']),
},
use: generateLoaders(['css-loader', 'postcss-loader', 'stylus-loader'])
}
]
}

View File

@ -7,8 +7,8 @@ var { VueLoaderPlugin } = require('vue-loader')
var env = process.env.NODE_ENV
// check env & config/index.js to decide weither to enable CSS Sourcemaps for the
// various preprocessor loaders added to vue-loader at the end of this file
var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
var cssSourceMapDev = env === 'development' && config.dev.cssSourceMap
var cssSourceMapProd = env === 'production' && config.build.productionSourceMap
var useCssSourceMap = cssSourceMapDev || cssSourceMapProd
var now = Date.now()
@ -18,9 +18,12 @@ module.exports = {
app: './src/main.js'
},
output: {
hashFunction: "sha256", // Workaround for builds with OpenSSL 3.
hashFunction: 'sha256', // Workaround for builds with OpenSSL 3.
path: config.build.assetsRoot,
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
publicPath:
process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath,
filename: '[name].js'
},
optimization: {
@ -30,17 +33,15 @@ module.exports = {
},
resolve: {
extensions: ['.js', '.jsx', '.vue', '.mjs'],
modules: [
path.join(__dirname, '../node_modules')
],
modules: [path.join(__dirname, '../node_modules')],
fallback: {
"url": require.resolve("url/"),
url: require.resolve('url/')
},
alias: {
'static': path.resolve(__dirname, '../static'),
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
'components': path.resolve(__dirname, '../src/components'),
static: path.resolve(__dirname, '../static'),
src: path.resolve(__dirname, '../src'),
assets: path.resolve(__dirname, '../src/assets'),
components: path.resolve(__dirname, '../src/components'),
'vue-i18n': 'vue-i18n/dist/vue-i18n.runtime.esm-bundler.js'
}
},
@ -66,14 +67,15 @@ module.exports = {
test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
type: 'javascript/auto',
loader: '@intlify/vue-i18n-loader',
include: [ // Use `Rule.include` to specify the files of locale messages to be pre-compiled
include: [
// Use `Rule.include` to specify the files of locale messages to be pre-compiled
path.resolve(__dirname, '../src/i18n')
]
},
{
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto"
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto'
},
{
test: /\.vue$/,
@ -114,10 +116,8 @@ module.exports = {
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
},
}
]
},
plugins: [
new VueLoaderPlugin()
]
plugins: [new VueLoaderPlugin()]
}

View File

@ -7,7 +7,9 @@ var HtmlWebpackPlugin = require('html-webpack-plugin')
// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(
baseWebpackConfig.entry[name]
)
})
module.exports = merge(baseWebpackConfig, {
@ -20,10 +22,10 @@ module.exports = merge(baseWebpackConfig, {
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env,
'COMMIT_HASH': JSON.stringify('DEV'),
'DEV_OVERRIDES': JSON.stringify(config.dev.settings),
'__VUE_OPTIONS_API__': true,
'__VUE_PROD_DEVTOOLS__': false
COMMIT_HASH: JSON.stringify('DEV'),
DEV_OVERRIDES: JSON.stringify(config.dev.settings),
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),

View File

@ -2,23 +2,27 @@ var path = require('path')
var config = require('../config')
var utils = require('./utils')
var webpack = require('webpack')
const WorkboxPlugin = require('workbox-webpack-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin')
var { merge } = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var MiniCssExtractPlugin = require('mini-css-extract-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var env = process.env.NODE_ENV === 'testing'
var env =
process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: config.build.env
let commitHash = require('child_process')
.execSync('git rev-parse --short HEAD')
.toString();
.execSync('git rev-parse --short HEAD')
.toString()
var webpackConfig = merge(baseWebpackConfig, {
mode: 'production',
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, extract: true })
rules: utils.styleLoaders({
sourceMap: config.dev.cssSourceMap,
extract: true
})
},
devtool: 'source-map',
optimization: {
@ -36,15 +40,15 @@ var webpackConfig = merge(baseWebpackConfig, {
new WorkboxPlugin.InjectManifest({
swSrc: path.join(__dirname, '..', 'src/sw.js'),
swDest: 'sw-pleroma.js',
maximumFileSizeToCacheInBytes: 15 * 1024 * 1024,
maximumFileSizeToCacheInBytes: 15 * 1024 * 1024
}),
// http://vuejs.github.io/vue-loader/workflow/production.html
new webpack.DefinePlugin({
'process.env': env,
'COMMIT_HASH': JSON.stringify(commitHash),
'DEV_OVERRIDES': JSON.stringify(undefined),
'__VUE_OPTIONS_API__': true,
'__VUE_PROD_DEVTOOLS__': false
COMMIT_HASH: JSON.stringify(commitHash),
DEV_OVERRIDES: JSON.stringify(undefined),
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
}),
// extract css into its own file
new MiniCssExtractPlugin({
@ -54,9 +58,8 @@ var webpackConfig = merge(baseWebpackConfig, {
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
filename:
process.env.NODE_ENV === 'testing' ? 'index.html' : config.build.index,
template: 'index.html',
inject: true,
minify: {
@ -69,7 +72,7 @@ var webpackConfig = merge(baseWebpackConfig, {
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'auto'
}),
})
// split vendor js into its own file
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
@ -87,9 +90,7 @@ if (config.build.productionGzip) {
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
'\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
),
threshold: 10240,
minRatio: 0.8

View File

@ -38,7 +38,7 @@ module.exports = {
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/manifest.json': {
'/manifest.json': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost'
@ -59,7 +59,7 @@ module.exports = {
cookieDomainRewrite: 'localhost',
ws: true,
headers: {
'Origin': target
Origin: target
}
},
'/oauth/revoke': {
@ -76,7 +76,7 @@ module.exports = {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost'
},
}
},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README

View File

@ -1,18 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1,user-scalable=no"
/>
<title>Akkoma</title>
<link rel="stylesheet" href="/static/font/css/fontello.css">
<link rel="stylesheet" href="/static/font/css/animation.css">
<link rel="stylesheet" href="/static/font/tiresias.css">
<link rel="stylesheet" href="/static/font/css/lato.css">
<link rel="stylesheet" href="/static/mfm.css">
<link rel="stylesheet" href="/static/custom.css">
<link
rel="stylesheet"
href="/static/font/css/fontello.css"
/>
<link
rel="stylesheet"
href="/static/font/css/animation.css"
/>
<link
rel="stylesheet"
href="/static/font/tiresias.css"
/>
<link
rel="stylesheet"
href="/static/font/css/lato.css"
/>
<link
rel="stylesheet"
href="/static/mfm.css"
/>
<link
rel="stylesheet"
href="/static/custom.css"
/>
<!--server-generated-meta-->
<link rel="icon" type="image/png" href="/favicon.png">
<link rel="manifest" href="/manifest.json">
<link
rel="icon"
type="image/png"
href="/favicon.png"
/>
<link
rel="manifest"
href="/manifest.json"
/>
</head>
<body class="hidden">
<noscript>To use Akkoma, please enable JavaScript.</noscript>

View File

@ -1,6 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
"extends": ["config:base"]
}

View File

@ -117,7 +117,6 @@
padding-top: 0.5em;
}
.play-icon {
position: absolute;
font-size: 64px;

View File

@ -8,7 +8,7 @@
flex: 0 0 0;
max-width: 9em;
align-items: stretch;
padding: .2em 8px;
padding: 0.2em 8px;
input {
background: none;
@ -40,9 +40,10 @@
}
.transparentIndicator {
// forgot to install counter-strike source, ooops
background-color: #FF00FF;
background-color: #ff00ff;
position: relative;
&::before, &::after {
&::before,
&::after {
display: block;
content: '';
background-color: #000000;
@ -64,5 +65,4 @@
.label {
flex: 1 1 auto;
}
}

View File

@ -15,7 +15,7 @@
display: grid;
grid-template-rows: var(--navbar-height);
grid-template-columns: 2fr auto 2fr;
grid-template-areas: "nav-left logo actions";
grid-template-areas: 'nav-left logo actions';
box-sizing: border-box;
padding: 0 1.2em;
margin: auto;
@ -24,11 +24,12 @@
&.-logoLeft .inner-nav {
grid-template-columns: auto 2fr 2fr;
grid-template-areas: "logo nav-left actions";
grid-template-areas: 'logo nav-left actions';
}
.button-default {
&, svg {
&,
svg {
color: $fallback--text;
color: var(--btnTopBarText, $fallback--text);
}
@ -49,7 +50,7 @@
color: $fallback--text;
color: var(--btnToggledTopBarText, $fallback--text);
background-color: $fallback--fg;
background-color: var(--btnToggledTopBar, $fallback--fg)
background-color: var(--btnToggledTopBar, $fallback--fg);
}
}

View File

@ -100,7 +100,7 @@
justify-content: center;
width: 32px;
height: 32px;
padding: .4em;
padding: 0.4em;
cursor: pointer;
img {
@ -133,7 +133,7 @@
}
.sticker-picker {
flex: 1 1 auto
flex: 1 1 auto;
}
.stickers,
@ -168,8 +168,8 @@
overflow: auto;
user-select: none;
mask: linear-gradient(to top, white 0, transparent 100%) bottom no-repeat,
linear-gradient(to bottom, white 0, transparent 100%) top no-repeat,
linear-gradient(to top, white, white);
linear-gradient(to bottom, white 0, transparent 100%) top no-repeat,
linear-gradient(to top, white, white);
transition: mask-size 150ms;
mask-size: 100% 20px, 100% 20px, auto;
// Autoprefixed seem to ignore this one, and also syntax is different
@ -221,7 +221,5 @@
max-height: 100%;
}
}
}
}

View File

@ -2,19 +2,21 @@
margin: 1em;
table {
width:100%;
width: 100%;
text-align: left;
padding-left:10px;
padding-bottom:20px;
padding-left: 10px;
padding-bottom: 20px;
th, td {
th,
td {
width: 180px;
max-width: 360px;
overflow: hidden;
overflow: hidden;
vertical-align: text-top;
}
th+th, td+td {
th + th,
td + td {
width: auto;
}
}

View File

@ -74,21 +74,23 @@
&.-striped {
& .shortName,
& .full {
background-image:
repeating-linear-gradient(
135deg,
var(--____highlight-tintColor),
var(--____highlight-tintColor) 5px,
var(--____highlight-tintColor2) 5px,
var(--____highlight-tintColor2) 10px
);
background-image: repeating-linear-gradient(
135deg,
var(--____highlight-tintColor),
var(--____highlight-tintColor) 5px,
var(--____highlight-tintColor2) 5px,
var(--____highlight-tintColor2) 10px
);
}
}
&.-solid {
& .shortName,
& .full {
background-image: linear-gradient(var(--____highlight-tintColor2), var(--____highlight-tintColor2));
background-image: linear-gradient(
var(--____highlight-tintColor2),
var(--____highlight-tintColor2)
);
}
}

View File

@ -6,7 +6,7 @@
margin: 1em 1em 1.4em;
> div {
margin-bottom: .5em;
margin-bottom: 0.5em;
&:last-child {
margin-bottom: 0;
}

View File

@ -2,19 +2,21 @@
margin: 1em;
table {
width:100%;
width: 100%;
text-align: left;
padding-left:10px;
padding-bottom:20px;
padding-left: 10px;
padding-bottom: 20px;
th, td {
th,
td {
width: 180px;
max-width: 360px;
overflow: hidden;
overflow: hidden;
vertical-align: text-top;
}
th+th, td+td {
th + th,
td + td {
width: auto;
}
}

View File

@ -9,12 +9,12 @@
// TODO Copypaste from Status, should unify it somehow
.Notification {
border-bottom: 1px solid;
border-color: $fallback--border;
border-color: var(--border, $fallback--border);
word-wrap: break-word;
word-break: break-word;
--emoji-size: 14px;
border-bottom: 1px solid;
border-color: $fallback--border;
border-color: var(--border, $fallback--border);
word-wrap: break-word;
word-break: break-word;
--emoji-size: 14px;
&:hover {
--_still-image-img-visibility: visible;

View File

@ -1,9 +1,15 @@
import { unescape, flattenDeep } from 'lodash'
import { getTagName, processTextForEmoji, getAttrs } from 'src/services/html_converter/utility.service.js'
import {
getTagName,
processTextForEmoji,
getAttrs
} from 'src/services/html_converter/utility.service.js'
import { convertHtmlToTree } from 'src/services/html_converter/html_tree_converter.service.js'
import { convertHtmlToLines } from 'src/services/html_converter/html_line_converter.service.js'
import StillImage from 'src/components/still-image/still-image.vue'
import MentionsLine, { MENTIONS_LIMIT } from 'src/components/mentions_line/mentions_line.vue'
import MentionsLine, {
MENTIONS_LIMIT
} from 'src/components/mentions_line/mentions_line.vue'
import HashtagLink from 'src/components/hashtag_link/hashtag_link.vue'
import './rich_content.scss'
@ -67,7 +73,7 @@ export default {
}
},
// NEVER EVER TOUCH DATA INSIDE RENDER
render () {
render() {
// Don't greentext MFM
const greentext = this.mfm ? false : this.greentext
@ -87,10 +93,12 @@ export default {
let tagsIndex = 0
const renderImage = (tag) => {
return <StillImage
{...getAttrs(tag)}
class="img"
/>
return (
<StillImage
{...getAttrs(tag)}
class="img"
/>
)
}
const renderHashtag = (attrs, children, encounteredTextReverse) => {
@ -100,12 +108,20 @@ export default {
lastTags.push(linkData)
}
const { url, tag, content } = linkData
return <HashtagLink url={url} tag={tag} content={content}/>
return (
<HashtagLink
url={url}
tag={tag}
content={content}
/>
)
}
const renderMention = (attrs, children) => {
const linkData = getLinkData(attrs, children, mentionIndex++)
linkData.notifying = this.attentions.some(a => a.statusnet_profile_url === linkData.url)
linkData.notifying = this.attentions.some(
(a) => a.statusnet_profile_url === linkData.url
)
writtenMentions.push(linkData)
if (currentMentions === null) {
currentMentions = []
@ -115,7 +131,7 @@ export default {
invisibleMentions.push(linkData)
}
if (currentMentions.length === 1) {
return <MentionsLine mentions={ currentMentions } />
return <MentionsLine mentions={currentMentions} />
} else {
return ''
}
@ -134,23 +150,26 @@ export default {
// in MentionsLine
lastSpacing = item
// Don't remove last space in a container (fixes poast mentions)
return (index !== array.length - 1) && (currentMentions !== null) ? item.trim() : item
return index !== array.length - 1 && currentMentions !== null
? item.trim()
: item
}
currentMentions = null
if (item.includes(':')) {
item = ['', processTextForEmoji(
item,
this.emoji,
({ shortcode, url }) => {
return <StillImage
class="emoji img"
src={url}
title={`:${shortcode}:`}
alt={`:${shortcode}:`}
/>
}
)]
item = [
'',
processTextForEmoji(item, this.emoji, ({ shortcode, url }) => {
return (
<StillImage
class="emoji img"
src={url}
title={`:${shortcode}:`}
alt={`:${shortcode}:`}
/>
)
})
]
}
return item
}
@ -166,12 +185,16 @@ export default {
* we have a tag right next to mentions
*/
const mentionsLinePadding =
// Padding is only needed if we just finished parsing mentions
previouslyMentions &&
// Don't add padding if content is string and has padding already
!(children && typeof children[0] === 'string' && children[0].match(/^\s/))
? lastSpacing
: ''
// Padding is only needed if we just finished parsing mentions
previouslyMentions &&
// Don't add padding if content is string and has padding already
!(
children &&
typeof children[0] === 'string' &&
children[0].match(/^\s/)
)
? lastSpacing
: ''
switch (Tag) {
case 'br':
currentMentions = null
@ -188,7 +211,11 @@ export default {
break
}
case 'span':
if (this.handleLinks && attrs['class'] && attrs['class'].includes('h-card')) {
if (
this.handleLinks &&
attrs['class'] &&
attrs['class'].includes('h-card')
) {
return ['', children.map(processItem), '']
}
}
@ -196,10 +223,7 @@ export default {
if (children !== undefined) {
return [
'',
[
mentionsLinePadding,
[opener, children.map(processItem), closer]
],
[mentionsLinePadding, [opener, children.map(processItem), closer]],
''
]
} else {
@ -228,16 +252,17 @@ export default {
// should only be this
if (
(attrs['class'] && attrs['class'].includes('hashtag')) || // Pleroma style
(attrs['rel'] === 'tag') // Mastodon style
attrs['rel'] === 'tag' // Mastodon style
) {
return renderHashtag(attrs, children, encounteredTextReverse)
} else {
attrs.target = '_blank'
const newChildren = [...children].reverse().map(processItemReverse).reverse()
const newChildren = [...children]
.reverse()
.map(processItemReverse)
.reverse()
return <a {...attrs}>
{ newChildren }
</a>
return <a {...attrs}>{newChildren}</a>
}
case '':
return [...children].reverse().map(processItemReverse).reverse()
@ -248,11 +273,9 @@ export default {
const newChildren = Array.isArray(children)
? [...children].reverse().map(processItemReverse).reverse()
: children
return <Tag {...getAttrs(opener)}>
{ newChildren }
</Tag>
return <Tag {...getAttrs(opener)}>{newChildren}</Tag>
} else {
return <Tag/>
return <Tag />
}
}
return item
@ -263,9 +286,7 @@ export default {
// DO NOT USE SLOTS they cause a re-render feedback loop here.
// slots updated -> rerender -> emit -> update up the tree -> rerender -> ...
// at least until vue3?
const result = <span class="RichContent">
{ pass2 }
</span>
const result = <span class="RichContent">{pass2}</span>
const event = {
lastTags,
@ -311,31 +332,36 @@ export const preProcessPerLine = (html, greentext) => {
const greentextHandle = new Set(['p', 'div'])
const lines = convertHtmlToLines(html)
const newHtml = lines.reverse().map((item, index, array) => {
if (!item.text) return item
const string = item.text
const newHtml = lines
.reverse()
.map((item, index, array) => {
if (!item.text) return item
const string = item.text
// Greentext stuff
if (
// Only if greentext is engaged
greentext &&
// Greentext stuff
if (
// Only if greentext is engaged
greentext &&
// Only handle p's and divs. Don't want to affect blockquotes, code etc
item.level.every(l => greentextHandle.has(l)) &&
item.level.every((l) => greentextHandle.has(l)) &&
// Only if line begins with '>' or '<'
(string.includes('&gt;') || string.includes('&lt;'))
) {
const cleanedString = string.replace(/<[^>]+?>/gi, '') // remove all tags
.replace(/@\w+/gi, '') // remove mentions (even failed ones)
.trim()
if (cleanedString.startsWith('&gt;')) {
return `<span class='greentext'>${string}</span>`
} else if (cleanedString.startsWith('&lt;')) {
return `<span class='cyantext'>${string}</span>`
) {
const cleanedString = string
.replace(/<[^>]+?>/gi, '') // remove all tags
.replace(/@\w+/gi, '') // remove mentions (even failed ones)
.trim()
if (cleanedString.startsWith('&gt;')) {
return `<span class='greentext'>${string}</span>`
} else if (cleanedString.startsWith('&lt;')) {
return `<span class='cyantext'>${string}</span>`
}
}
}
return string
}).reverse().join('')
return string
})
.reverse()
.join('')
return { newHtml }
}

View File

@ -10,7 +10,7 @@
margin-bottom: 0.5em;
}
.suboptions {
margin-top: 0.3em
margin-top: 0.3em;
}
}
@ -49,7 +49,7 @@
height: 100%;
}
>.panel-body {
> .panel-body {
height: 100%;
overflow-y: hidden;
@ -63,7 +63,7 @@
.settings-footer {
display: flex;
>* {
> * {
margin-right: 0.5em;
}

View File

@ -10,7 +10,7 @@
> div,
> label {
display: block;
margin-bottom: .5em;
margin-bottom: 0.5em;
&:last-child {
margin-bottom: 0;
}
@ -21,7 +21,7 @@
.option-list {
margin: 0;
padding-left: .5em;
padding-left: 0.5em;
}
}

View File

@ -1,29 +1,29 @@
.mutes-and-blocks-tab {
height: 100%;
height: 100%;
.usersearch-wrapper {
padding: 1em;
}
.usersearch-wrapper {
padding: 1em;
}
.bulk-actions {
text-align: right;
padding: 0 1em;
min-height: 2em;
}
.bulk-actions {
text-align: right;
padding: 0 1em;
min-height: 2em;
}
.bulk-action-button {
width: 10em
}
.bulk-action-button {
width: 10em;
}
.domain-mute-form {
padding: 1em;
display: flex;
flex-direction: column
}
.domain-mute-form {
padding: 1em;
display: flex;
flex-direction: column;
}
.domain-mute-button {
align-self: flex-end;
margin-top: 1em;
width: 10em
}
.domain-mute-button {
align-self: flex-end;
margin-top: 1em;
width: 10em;
}
}

View File

@ -12,7 +12,7 @@
padding-top: 5px;
}
input[type=file] {
input[type='file'] {
padding: 5px;
height: auto;
}

View File

@ -4,10 +4,10 @@
.theme-warning {
display: flex;
align-items: baseline;
margin-bottom: .5em;
margin-bottom: 0.5em;
.buttons {
.btn {
margin-bottom: .5em;
margin-bottom: 0.5em;
}
}
}
@ -25,29 +25,31 @@
}
&.disabled {
input, select {
opacity: .5
input,
select {
opacity: 0.5;
}
}
.opt {
margin: .5em;
margin: 0.5em;
}
.color-input {
flex: 0 0 0;
}
input, select {
input,
select {
min-width: 3em;
margin: 0;
flex: 0;
&[type=number] {
&[type='number'] {
min-width: 5em;
}
&[type=range] {
&[type='range'] {
flex: 1;
min-width: 3em;
align-self: flex-start;
@ -63,8 +65,7 @@
.reset-container,
.apply-container,
.radius-container,
.color-container,
{
.color-container {
display: flex;
}
@ -73,7 +74,7 @@
flex-direction: column;
}
.color-container{
.color-container {
> h4 {
width: 99%;
}
@ -100,7 +101,7 @@
p {
flex: 1;
margin: 0;
margin-right: .5em;
margin-right: 0.5em;
}
}
@ -112,14 +113,14 @@
min-width: 1px;
flex: 0 auto;
padding: 0 1em;
margin-bottom: .5em;
margin-bottom: 0.5em;
}
}
.shadow-selector {
.override {
flex: 1;
margin-left: .5em;
margin-left: 0.5em;
}
.select-container {
margin-top: -4px;
@ -136,7 +137,7 @@
.presets,
.import-export {
margin-bottom: .5em;
margin-bottom: 0.5em;
}
.import-export {
@ -144,16 +145,16 @@
}
.override {
margin-left: .5em;
margin-left: 0.5em;
}
}
.save-load-options {
flex-wrap: wrap;
margin-top: .5em;
margin-top: 0.5em;
justify-content: center;
.keep-option {
margin: 0 .5em .5em;
margin: 0 0.5em 0.5em;
min-width: 25%;
}
}
@ -179,11 +180,11 @@
flex: 1;
h4 {
margin-bottom: .25em;
margin-bottom: 0.25em;
}
.icons {
margin-top: .5em;
margin-top: 0.5em;
display: flex;
i {
@ -199,8 +200,19 @@
align-items: center;
}
.avatar, .avatar-alt{
background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
.avatar,
.avatar-alt {
background: linear-gradient(
135deg,
#b8e1fc 0%,
#a9d2f3 10%,
#90bae4 25%,
#90bcea 37%,
#90bff0 50%,
#6ba8e5 51%,
#a2daf5 83%,
#bdf3fd 100%
);
color: black;
font-family: sans-serif;
text-align: center;
@ -255,21 +267,21 @@
.color-item {
min-width: 20em;
margin: 5px 6px 0 0;
display:flex;
display: flex;
flex-direction: column;
flex: 1 1 0;
&.wide {
min-width: 60%
min-width: 60%;
}
&:not(.wide):nth-child(2n+1) {
&:not(.wide):nth-child(2n + 1) {
margin-right: 7px;
}
.color, .opacity {
display:flex;
.color,
.opacity {
display: flex;
align-items: baseline;
}
}
@ -301,7 +313,7 @@
flex: 1;
}
.theme-radius-lb{
.theme-radius-lb {
max-width: 50em;
}
@ -310,8 +322,8 @@
}
.btn {
margin-left: .25em;
margin-right: .25em;
margin-left: 0.25em;
margin-right: 0.25em;
}
}

View File

@ -105,8 +105,8 @@
.media-body-wrapper {
min-height: 0;
mask:
linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat,
mask: linear-gradient(to top, white, transparent) bottom/100% 70px
no-repeat,
linear-gradient(to top, white, white);
/* Autoprefixed seem to ignore this one, and also syntax is different */
@ -210,4 +210,3 @@
}
}
}

View File

@ -5,7 +5,7 @@ import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
import './tab_switcher.scss'
const findFirstUsable = (slots) => slots.findIndex(_ => _.props)
const findFirstUsable = (slots) => slots.findIndex((_) => _.props)
export default {
name: 'TabSwitcher',
@ -41,58 +41,61 @@ export default {
default: false
}
},
data () {
data() {
return {
active: findFirstUsable(this.slots())
}
},
computed: {
activeIndex () {
activeIndex() {
// In case of controlled component
if (this.activeTab) {
return this.slots().findIndex(slot => slot && slot.props && this.activeTab === slot.props.key)
return this.slots().findIndex(
(slot) => slot && slot.props && this.activeTab === slot.props.key
)
} else {
return this.active
}
},
isActive () {
return tabName => {
const isWanted = slot => slot.props && slot.props['data-tab-name'] === tabName
isActive() {
return (tabName) => {
const isWanted = (slot) =>
slot.props && slot.props['data-tab-name'] === tabName
return this.$slots.default().findIndex(isWanted) === this.activeIndex
}
},
settingsModalVisible () {
settingsModalVisible() {
return this.settingsModalState === 'visible'
},
modModalVisible () {
modModalVisible() {
return this.modModalState === 'visible'
},
...mapState({
settingsModalState: state => state.interface.settingsModalState,
modModalState: state => state.interface.modModalState
settingsModalState: (state) => state.interface.settingsModalState,
modModalState: (state) => state.interface.modModalState
})
},
beforeUpdate () {
beforeUpdate() {
const currentSlot = this.slots()[this.active]
if (!currentSlot.props) {
this.active = findFirstUsable(this.slots())
}
},
methods: {
clickTab (index) {
clickTab(index) {
return (e) => {
e.preventDefault()
this.setTab(index)
}
},
// DO NOT put it to computed, it doesn't work (caching?)
slots () {
slots() {
if (this.$slots.default()[0].type === Fragment) {
return this.$slots.default()[0].children
}
return this.$slots.default()
},
setTab (index) {
setTab(index) {
if (typeof this.onSwitch === 'function') {
this.onSwitch.call(null, this.slots()[index].key)
}
@ -102,32 +105,17 @@ export default {
}
}
},
render () {
const tabs = this.slots()
.map((slot, index) => {
const props = slot.props
if (!props) return
const classesTab = ['tab', 'button-default']
const classesWrapper = ['tab-wrapper']
if (this.activeIndex === index) {
classesTab.push('active')
classesWrapper.push('active')
}
if (props.image) {
return (
<div class={classesWrapper.join(' ')}>
<button
disabled={props.disabled}
onClick={this.clickTab(index)}
class={classesTab.join(' ')}
type="button"
>
<img src={props.image} title={props['image-tooltip']}/>
{props.label ? '' : props.label}
</button>
</div>
)
}
render() {
const tabs = this.slots().map((slot, index) => {
const props = slot.props
if (!props) return
const classesTab = ['tab', 'button-default']
const classesWrapper = ['tab-wrapper']
if (this.activeIndex === index) {
classesTab.push('active')
classesWrapper.push('active')
}
if (props.image) {
return (
<div class={classesWrapper.join(' ')}>
<button
@ -136,44 +124,62 @@ export default {
class={classesTab.join(' ')}
type="button"
>
{!props.icon ? '' : (<FAIcon class="tab-icon" size="2x" fixed-width icon={props.icon}/>)}
<span class="text">
{props.label}
</span>
<img
src={props.image}
title={props['image-tooltip']}
/>
{props.label ? '' : props.label}
</button>
</div>
)
})
}
return (
<div class={classesWrapper.join(' ')}>
<button
disabled={props.disabled}
onClick={this.clickTab(index)}
class={classesTab.join(' ')}
type="button"
>
{!props.icon ? (
''
) : (
<FAIcon
class="tab-icon"
size="2x"
fixed-width
icon={props.icon}
/>
)}
<span class="text">{props.label}</span>
</button>
</div>
)
})
const contents = this.slots().map((slot, index) => {
const props = slot.props
if (!props) return
const active = this.activeIndex === index
const classes = [ active ? 'active' : 'hidden' ]
const classes = [active ? 'active' : 'hidden']
if (props.fullHeight) {
classes.push('full-height')
}
const renderSlot = (!this.renderOnlyFocused || active)
? slot
: ''
const renderSlot = !this.renderOnlyFocused || active ? slot : ''
return (
<div class={classes}>
{
this.sideTabBar
? <h1 class="mobile-label">{props.label}</h1>
: ''
}
{this.sideTabBar ? <h1 class="mobile-label">{props.label}</h1> : ''}
{renderSlot}
</div>
)
})
return (
<div class={'tab-switcher ' + (this.sideTabBar ? 'side-tabs' : 'top-tabs')}>
<div class="tabs">
{tabs}
</div>
<div
class={'tab-switcher ' + (this.sideTabBar ? 'side-tabs' : 'top-tabs')}
>
<div class="tabs">{tabs}</div>
<div
ref="contents"
class={'contents' + (this.scrollableTabs ? ' scrollable-tabs' : '')}

View File

@ -22,7 +22,8 @@
}
.timeline-heading {
.button-default, .alert {
.button-default,
.alert {
line-height: 2em;
width: 100%;
}

View File

@ -6,104 +6,113 @@ import './with_load_more.scss'
import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faCircleNotch
} from '@fortawesome/free-solid-svg-icons'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
library.add(
faCircleNotch
)
library.add(faCircleNotch)
const withLoadMore = ({
fetch, // function to fetch entries and return a promise
select, // function to select data from store
unmounted, // function called at "destroyed" lifecycle
childPropName = 'entries', // name of the prop to be passed into the wrapped component
additionalPropNames = [] // additional prop name list of the wrapper component
}) => (WrappedComponent) => {
const originalProps = Object.keys(getComponentProps(WrappedComponent))
const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
const withLoadMore =
({
fetch, // function to fetch entries and return a promise
select, // function to select data from store
unmounted, // function called at "destroyed" lifecycle
childPropName = 'entries', // name of the prop to be passed into the wrapped component
additionalPropNames = [] // additional prop name list of the wrapper component
}) =>
(WrappedComponent) => {
const originalProps = Object.keys(getComponentProps(WrappedComponent))
const props = originalProps
.filter((v) => v !== childPropName)
.concat(additionalPropNames)
return {
props,
data () {
return {
loading: false,
bottomedOut: false,
error: false,
entries: []
}
},
created () {
window.addEventListener('scroll', this.scrollLoad)
if (this.entries.length === 0) {
this.fetchEntries()
}
},
unmounted () {
window.removeEventListener('scroll', this.scrollLoad)
unmounted && unmounted(this.$props, this.$store)
},
methods: {
// Entries is not a computed because computed can't track the dynamic
// selector for changes and won't trigger after fetch.
updateEntries () {
this.entries = select(this.$props, this.$store) || []
},
fetchEntries () {
if (!this.loading) {
this.loading = true
this.error = false
fetch(this.$props, this.$store)
.then((newEntries) => {
this.loading = false
this.bottomedOut = isEmpty(newEntries)
})
.catch(() => {
this.loading = false
this.error = true
})
.finally(() => {
this.updateEntries()
})
return {
props,
data() {
return {
loading: false,
bottomedOut: false,
error: false,
entries: []
}
},
scrollLoad (e) {
const bodyBRect = document.body.getBoundingClientRect()
const height = Math.max(bodyBRect.height, -(bodyBRect.y))
if (this.loading === false &&
this.bottomedOut === false &&
this.$el.offsetHeight > 0 &&
(window.innerHeight + window.pageYOffset) >= (height - 750)
) {
created() {
window.addEventListener('scroll', this.scrollLoad)
if (this.entries.length === 0) {
this.fetchEntries()
}
}
},
render () {
const props = {
...this.$props,
[childPropName]: this.entries
}
const children = this.$slots
return (
<div class="with-load-more">
<WrappedComponent {...props}>
{children}
</WrappedComponent>
<div class="with-load-more-footer">
{this.error &&
<button onClick={this.fetchEntries} class="button-unstyled -link -fullwidth alert error">
{this.$t('general.generic_error')}
</button>
}
{!this.error && this.loading && <FAIcon spin icon="circle-notch"/>}
{!this.error && !this.loading && !this.bottomedOut && <a onClick={this.fetchEntries}>{this.$t('general.more')}</a>}
},
unmounted() {
window.removeEventListener('scroll', this.scrollLoad)
unmounted && unmounted(this.$props, this.$store)
},
methods: {
// Entries is not a computed because computed can't track the dynamic
// selector for changes and won't trigger after fetch.
updateEntries() {
this.entries = select(this.$props, this.$store) || []
},
fetchEntries() {
if (!this.loading) {
this.loading = true
this.error = false
fetch(this.$props, this.$store)
.then((newEntries) => {
this.loading = false
this.bottomedOut = isEmpty(newEntries)
})
.catch(() => {
this.loading = false
this.error = true
})
.finally(() => {
this.updateEntries()
})
}
},
scrollLoad(e) {
const bodyBRect = document.body.getBoundingClientRect()
const height = Math.max(bodyBRect.height, -bodyBRect.y)
if (
this.loading === false &&
this.bottomedOut === false &&
this.$el.offsetHeight > 0 &&
window.innerHeight + window.pageYOffset >= height - 750
) {
this.fetchEntries()
}
}
},
render() {
const props = {
...this.$props,
[childPropName]: this.entries
}
const children = this.$slots
return (
<div class="with-load-more">
<WrappedComponent {...props}>{children}</WrappedComponent>
<div class="with-load-more-footer">
{this.error && (
<button
onClick={this.fetchEntries}
class="button-unstyled -link -fullwidth alert error"
>
{this.$t('general.generic_error')}
</button>
)}
{!this.error && this.loading && (
<FAIcon
spin
icon="circle-notch"
/>
)}
{!this.error && !this.loading && !this.bottomedOut && (
<a onClick={this.fetchEntries}>{this.$t('general.more')}</a>
)}
</div>
</div>
</div>
)
)
}
}
}
}
export default withLoadMore

View File

@ -1,4 +1,3 @@
@import '../../_variables.scss';
.with-load-more {

View File

@ -6,86 +6,93 @@ import './with_subscription.scss'
import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faCircleNotch
} from '@fortawesome/free-solid-svg-icons'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
library.add(
faCircleNotch
)
library.add(faCircleNotch)
const withSubscription = ({
fetch, // function to fetch entries and return a promise
select, // function to select data from store
childPropName = 'content', // name of the prop to be passed into the wrapped component
additionalPropNames = [] // additional prop name list of the wrapper component
}) => (WrappedComponent) => {
const originalProps = Object.keys(getComponentProps(WrappedComponent))
const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
const withSubscription =
({
fetch, // function to fetch entries and return a promise
select, // function to select data from store
childPropName = 'content', // name of the prop to be passed into the wrapped component
additionalPropNames = [] // additional prop name list of the wrapper component
}) =>
(WrappedComponent) => {
const originalProps = Object.keys(getComponentProps(WrappedComponent))
const props = originalProps
.filter((v) => v !== childPropName)
.concat(additionalPropNames)
return {
props: [
...props,
'refresh' // boolean saying to force-fetch data whenever created
],
data () {
return {
loading: false,
error: false
}
},
computed: {
fetchedData () {
return select(this.$props, this.$store)
}
},
created () {
if (this.refresh || isEmpty(this.fetchedData)) {
this.fetchData()
}
},
methods: {
fetchData () {
if (!this.loading) {
this.loading = true
this.error = false
fetch(this.$props, this.$store)
.then(() => {
this.loading = false
})
.catch(() => {
this.error = true
this.loading = false
})
return {
props: [
...props,
'refresh' // boolean saying to force-fetch data whenever created
],
data() {
return {
loading: false,
error: false
}
}
},
render () {
if (!this.error && !this.loading) {
const props = {
...this.$props,
[childPropName]: this.fetchedData
},
computed: {
fetchedData() {
return select(this.$props, this.$store)
}
},
created() {
if (this.refresh || isEmpty(this.fetchedData)) {
this.fetchData()
}
},
methods: {
fetchData() {
if (!this.loading) {
this.loading = true
this.error = false
fetch(this.$props, this.$store)
.then(() => {
this.loading = false
})
.catch(() => {
this.error = true
this.loading = false
})
}
}
},
render() {
if (!this.error && !this.loading) {
const props = {
...this.$props,
[childPropName]: this.fetchedData
}
const children = this.$slots
return (
<div class="with-subscription">
<WrappedComponent {...props}>{children}</WrappedComponent>
</div>
)
} else {
return (
<div class="with-subscription-loading">
{this.error ? (
<a
onClick={this.fetchData}
class="alert error"
>
{this.$t('general.generic_error')}
</a>
) : (
<FAIcon
spin
icon="circle-notch"
/>
)}
</div>
)
}
const children = this.$slots
return (
<div class="with-subscription">
<WrappedComponent {...props}>
{children}
</WrappedComponent>
</div>
)
} else {
return (
<div class="with-subscription-loading">
{this.error
? <a onClick={this.fetchData} class="alert error">{this.$t('general.generic_error')}</a>
: <FAIcon spin icon="circle-notch"/>
}
</div>
)
}
}
}
}
export default withSubscription

View File

@ -7,4 +7,4 @@
font-size: 1rem;
}
}
}
}

View File

@ -17,10 +17,14 @@ exports.assertion = function (selector, count) {
}
this.command = function (cb) {
var self = this
return this.api.execute(function (selector) {
return document.querySelectorAll(selector).length
}, [selector], function (res) {
cb.call(self, res)
})
return this.api.execute(
function (selector) {
return document.querySelectorAll(selector).length
},
[selector],
function (res) {
cb.call(self, res)
}
)
}
}

View File

@ -3,43 +3,45 @@ var config = require('../../config')
// http://nightwatchjs.org/guide#settings-file
module.exports = {
'src_folders': ['test/e2e/specs'],
'output_folder': 'test/e2e/reports',
'custom_assertions_path': ['test/e2e/custom-assertions'],
src_folders: ['test/e2e/specs'],
output_folder: 'test/e2e/reports',
custom_assertions_path: ['test/e2e/custom-assertions'],
'selenium': {
'start_process': true,
'server_path': 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar',
'host': '127.0.0.1',
'port': 4444,
'cli_args': {
selenium: {
start_process: true,
server_path:
'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar',
host: '127.0.0.1',
port: 4444,
cli_args: {
'webdriver.chrome.driver': require('chromedriver').path
}
},
'test_settings': {
'default': {
'selenium_port': 4444,
'selenium_host': 'localhost',
'silent': true,
'globals': {
'devServerURL': 'http://localhost:' + (process.env.PORT || config.dev.port)
test_settings: {
default: {
selenium_port: 4444,
selenium_host: 'localhost',
silent: true,
globals: {
devServerURL:
'http://localhost:' + (process.env.PORT || config.dev.port)
}
},
'chrome': {
'desiredCapabilities': {
'browserName': 'chrome',
'javascriptEnabled': true,
'acceptSslCerts': true
chrome: {
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true
}
},
'firefox': {
'desiredCapabilities': {
'browserName': 'firefox',
'javascriptEnabled': true,
'acceptSslCerts': true
firefox: {
desiredCapabilities: {
browserName: 'firefox',
javascriptEnabled: true,
acceptSslCerts: true
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -63,16 +63,12 @@ module.exports = function (config) {
frameworks: ['mocha', 'sinon-chai'],
reporters: ['mocha'],
customLaunchers: {
'FirefoxHeadless': {
FirefoxHeadless: {
base: 'Firefox',
flags: [
'-headless'
]
flags: ['-headless']
}
},
files: [
'./index.js'
],
files: ['./index.js'],
preprocessors: {
'./index.js': ['webpack', 'sourcemap']
},
@ -85,10 +81,7 @@ module.exports = function (config) {
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' }
]
reporters: [{ type: 'lcov', subdir: '.' }, { type: 'text-summary' }]
}
})
}

View File

@ -26,10 +26,10 @@ const run = () => {
let data = fs.readFileSync(newEmojiFilename, 'utf8')
// First filter out anything that's more than one codepoint
const newEmojis = JSON.parse(data).emojis.filter(e => e.emoji.length <= 2)
const newEmojis = JSON.parse(data).emojis.filter((e) => e.emoji.length <= 2)
// Create a table with format { shortname: emoji }, remove the :
newEmojis.forEach(e => {
newEmojis.forEach((e) => {
const name = e.shortname.slice(1, e.shortname.length - 1).toLowerCase()
if (name.length > 0) {
newEmojisObject[name] = e.emoji
@ -41,27 +41,34 @@ const run = () => {
emojisObject = JSON.parse(data)
// Get rid of longer emojis that don't play nice with reactions
Object.keys(emojisObject).forEach(e => {
Object.keys(emojisObject).forEach((e) => {
if (emojisObject[e].length > 2) emojisObject[e] = undefined
})
// Add new emojis from the new tables to the old table
Object.keys(newEmojisObject).forEach(e => {
Object.keys(newEmojisObject).forEach((e) => {
if (!emojisObject[e] && newEmojisObject[e].length <= 2) {
emojisObject[e] = newEmojisObject[e]
}
})
// Sort by key
const sorted = Object.keys(emojisObject).sort().reduce((acc, key) => {
if (key.length === 0) return acc
acc[key] = emojisObject[key]
return acc
}, {})
const sorted = Object.keys(emojisObject)
.sort()
.reduce((acc, key) => {
if (key.length === 0) return acc
acc[key] = emojisObject[key]
return acc
}, {})
fs.writeFile(outputFilename, JSON.stringify(sorted, null, 2), 'utf8', (err) => {
if (err) console.log('Error writing file', err)
})
fs.writeFile(
outputFilename,
JSON.stringify(sorted, null, 2),
'utf8',
(err) => {
if (err) console.log('Error writing file', err)
}
)
}
run()