kopia lustrzana https://github.com/nolanlawson/pinafore
				
				
				
			start on instance theming
							rodzic
							
								
									eaaacdeef5
								
							
						
					
					
						commit
						f69797544d
					
				| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
#!/usr/bin/env node
 | 
			
		||||
 | 
			
		||||
const sass = require('node-sass')
 | 
			
		||||
const chokidar = require('chokidar')
 | 
			
		||||
const argv = require('yargs').argv
 | 
			
		||||
const path = require('path')
 | 
			
		||||
const debounce = require('lodash/debounce')
 | 
			
		||||
const fs = require('fs')
 | 
			
		||||
const pify = require('pify')
 | 
			
		||||
const writeFile = pify(fs.writeFile.bind(fs))
 | 
			
		||||
const readdir = pify(fs.readdir.bind(fs))
 | 
			
		||||
const render = pify(sass.render.bind(sass))
 | 
			
		||||
 | 
			
		||||
const globalScss = path.join(__dirname, '../scss/global.scss')
 | 
			
		||||
const defaultThemeScss = path.join(__dirname, '../scss/themes/_default.scss')
 | 
			
		||||
const globalCss = path.join(__dirname, '../assets/global.css')
 | 
			
		||||
const scssDir = path.join(__dirname, '../scss')
 | 
			
		||||
const themesScssDir = path.join(__dirname, '../scss/themes')
 | 
			
		||||
const assetsDir = path.join(__dirname, '../assets')
 | 
			
		||||
 | 
			
		||||
function doWatch() {
 | 
			
		||||
  chokidar.watch(scssDir).on('change', debounce(() => {
 | 
			
		||||
    compileGlobalSass()
 | 
			
		||||
    compileThemesSass()
 | 
			
		||||
  }, 500))
 | 
			
		||||
  chokidar.watch()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function compileGlobalSass() {
 | 
			
		||||
  let results = await Promise.all([
 | 
			
		||||
    render({file: defaultThemeScss}),
 | 
			
		||||
    render({file: globalScss})
 | 
			
		||||
  ])
 | 
			
		||||
 | 
			
		||||
  let css = results.map(_ => _.css).join('\n')
 | 
			
		||||
 | 
			
		||||
  await writeFile(globalCss, css, 'utf8')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function compileThemesSass() {
 | 
			
		||||
  let files = (await readdir(themesScssDir)).filter(file => !path.basename(file).startsWith('_'))
 | 
			
		||||
  await Promise.all(files.map(async file => {
 | 
			
		||||
    let res = await render({file: path.join(themesScssDir, file)})
 | 
			
		||||
    await writeFile(path.join(assetsDir, path.basename(file).replace(/\.scss$/, '.css')), res.css, 'utf8')
 | 
			
		||||
  }))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function main() {
 | 
			
		||||
  await Promise.all([compileGlobalSass(), compileThemesSass()])
 | 
			
		||||
  if (argv.watch) {
 | 
			
		||||
    doWatch()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Promise.resolve().then(main).catch(err => {
 | 
			
		||||
  console.error(err)
 | 
			
		||||
  process.exit(1)
 | 
			
		||||
})
 | 
			
		||||
										
											
												Plik diff jest za duży
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								package.json
								
								
								
								
							
							
						
						
									
										10
									
								
								package.json
								
								
								
								
							| 
						 | 
				
			
			@ -6,13 +6,14 @@
 | 
			
		|||
    "dev": "concurrently --kill-others \"npm run build-sass-watch\" \"node server.js\"",
 | 
			
		||||
    "build": "npm run build-sass && sapper build",
 | 
			
		||||
    "start": "cross-env NODE_ENV=production node server.js",
 | 
			
		||||
    "build-sass": "node-sass scss -o assets",
 | 
			
		||||
    "build-sass-watch": "npm run build-sass && node-sass -w scss -o assets",
 | 
			
		||||
    "build-sass": "node ./bin/build-sass",
 | 
			
		||||
    "build-sass-watch": "node ./bin/build-sass --watch",
 | 
			
		||||
    "cy:run": "cypress run",
 | 
			
		||||
    "cy:open": "cypress open",
 | 
			
		||||
    "test": "run-p --race dev cy:run"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "chokidar": "^2.0.0",
 | 
			
		||||
    "compression": "^1.7.1",
 | 
			
		||||
    "concurrently": "^3.5.1",
 | 
			
		||||
    "cross-env": "^5.1.3",
 | 
			
		||||
| 
						 | 
				
			
			@ -22,9 +23,11 @@
 | 
			
		|||
    "font-awesome-svg-png": "^1.2.2",
 | 
			
		||||
    "glob": "^7.1.2",
 | 
			
		||||
    "idb": "^2.0.4",
 | 
			
		||||
    "lodash": "^4.17.4",
 | 
			
		||||
    "node-fetch": "^1.7.3",
 | 
			
		||||
    "node-sass": "^4.7.2",
 | 
			
		||||
    "npm-run-all": "^4.1.2",
 | 
			
		||||
    "pify": "^3.0.0",
 | 
			
		||||
    "sapper": "^0.3.1",
 | 
			
		||||
    "serve-static": "^1.13.1",
 | 
			
		||||
    "style-loader": "^0.19.1",
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +35,8 @@
 | 
			
		|||
    "svelte-loader": "^2.3.3",
 | 
			
		||||
    "uglifyjs-webpack-plugin": "^1.1.5",
 | 
			
		||||
    "url-search-params": "^0.10.0",
 | 
			
		||||
    "webpack": "^3.10.0"
 | 
			
		||||
    "webpack": "^3.10.0",
 | 
			
		||||
    "yargs": "^10.1.1"
 | 
			
		||||
  },
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "node": ">= 8"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
const themes = [
 | 
			
		||||
  {
 | 
			
		||||
    name: 'default',
 | 
			
		||||
    label: 'Royal (default)'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'scarlet',
 | 
			
		||||
    label: 'Scarlet'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: 'hotpants',
 | 
			
		||||
    label: 'Hotpants'
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export { themes }
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +74,14 @@ store.compute(
 | 
			
		|||
    }, loggedInInstances[currentInstance])
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
store.compute(
 | 
			
		||||
  'currentTheme',
 | 
			
		||||
  ['currentInstance', 'instanceThemes'],
 | 
			
		||||
  (currentInstance, instanceThemes) => {
 | 
			
		||||
    return instanceThemes[currentInstance] || 'default'
 | 
			
		||||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if (process.browser && process.env.NODE_ENV !== 'production') {
 | 
			
		||||
  window.store = store // for debugging
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,20 +15,14 @@
 | 
			
		|||
    </div>
 | 
			
		||||
    <h2>Theme:</h2>
 | 
			
		||||
    <form class="theme-chooser">
 | 
			
		||||
      <div class="theme-group">
 | 
			
		||||
        <input type="radio" name="current-theme" id="theme-default" value="default">
 | 
			
		||||
        <label for="theme-default">Royal (default)</label>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="theme-group">
 | 
			
		||||
        <input type="radio" name="current-theme" id="theme-crimson"
 | 
			
		||||
               value="crimson">
 | 
			
		||||
        <label for="theme-crimson">Crimson and Clover</label>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="theme-group">
 | 
			
		||||
        <input type="radio" name="current-theme" id="theme-hotpants"
 | 
			
		||||
               value="hotpants">
 | 
			
		||||
        <label for="theme-hotpants">Hot Pants</label>
 | 
			
		||||
      </div>
 | 
			
		||||
      {{#each themes as theme}}
 | 
			
		||||
        <div class="theme-group">
 | 
			
		||||
          <input type="radio" id="choice-theme-{{theme.name}}"
 | 
			
		||||
                 value="{{theme.name}}" checked="$currentTheme === theme.name"
 | 
			
		||||
                 bind:group="selectedTheme" on:change="onThemeChange()">
 | 
			
		||||
          <label for="choice-theme-{{theme.name}}">{{theme.label}}</label>
 | 
			
		||||
        </div>
 | 
			
		||||
      {{/each}}
 | 
			
		||||
    </form>
 | 
			
		||||
    {{/if}}
 | 
			
		||||
  </SettingsLayout>
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +60,7 @@
 | 
			
		|||
  import Layout from '../../_components/Layout.html'
 | 
			
		||||
  import SettingsLayout from '../_components/SettingsLayout.html'
 | 
			
		||||
  import { getCurrentUser } from '../../_utils/mastodon/user'
 | 
			
		||||
  import { themes } from '../../_static/themes'
 | 
			
		||||
 | 
			
		||||
  export default {
 | 
			
		||||
    components: {
 | 
			
		||||
| 
						 | 
				
			
			@ -73,10 +68,26 @@
 | 
			
		|||
      SettingsLayout
 | 
			
		||||
    },
 | 
			
		||||
    store: () => store,
 | 
			
		||||
    data: () => ({
 | 
			
		||||
      themes: themes
 | 
			
		||||
    }),
 | 
			
		||||
    oncreate: async function () {
 | 
			
		||||
      let currentInstanceData = this.store.get('currentInstanceData')
 | 
			
		||||
      let currentUser = await getCurrentUser(currentInstanceData.name, currentInstanceData.access_token)
 | 
			
		||||
      this.set({currentUser: currentUser})
 | 
			
		||||
      this.set({
 | 
			
		||||
        currentUser: currentUser,
 | 
			
		||||
        selectedTheme: this.store.get('currentTheme')
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
      onThemeChange () {
 | 
			
		||||
        let newTheme = this.get('selectedTheme')
 | 
			
		||||
        let instanceName = this.store.get('currentInstance')
 | 
			
		||||
        let instanceThemes = this.store.get('instanceThemes')
 | 
			
		||||
        instanceThemes[instanceName] = newTheme
 | 
			
		||||
        this.store.set({instanceThemes: instanceThemes})
 | 
			
		||||
        this.store.save()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +1,4 @@
 | 
			
		|||
:root {
 | 
			
		||||
  $main-theme-color: royalblue; // also: crimson, forestgreen, hotpink
 | 
			
		||||
  $anchor-color: $main-theme-color;
 | 
			
		||||
  $main-text-color: #333;
 | 
			
		||||
  $border-color: #dadada;
 | 
			
		||||
  $main-bg-color: white;
 | 
			
		||||
  $secondary-text-color: white;
 | 
			
		||||
 | 
			
		||||
@mixin baseTheme() {
 | 
			
		||||
  --button-primary-bg: lighten($main-theme-color, 7%);
 | 
			
		||||
  --button-primary-text: $secondary-text-color;
 | 
			
		||||
  --button-primary-border: darken($main-theme-color, 30%);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
$main-theme-color: royalblue;
 | 
			
		||||
$anchor-color: $main-theme-color;
 | 
			
		||||
$main-text-color: #333;
 | 
			
		||||
$border-color: #dadada;
 | 
			
		||||
$main-bg-color: white;
 | 
			
		||||
$secondary-text-color: white;
 | 
			
		||||
 | 
			
		||||
@import "_base.scss";
 | 
			
		||||
 | 
			
		||||
:root {
 | 
			
		||||
  @include baseTheme()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
$main-theme-color: hotpink;
 | 
			
		||||
$anchor-color: $main-theme-color;
 | 
			
		||||
$main-text-color: #333;
 | 
			
		||||
$border-color: #dadada;
 | 
			
		||||
$main-bg-color: white;
 | 
			
		||||
$secondary-text-color: white;
 | 
			
		||||
 | 
			
		||||
@import "_base.scss";
 | 
			
		||||
 | 
			
		||||
body.theme-hotpants {
 | 
			
		||||
  @include baseTheme()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
$main-theme-color: crimson;
 | 
			
		||||
$anchor-color: $main-theme-color;
 | 
			
		||||
$main-text-color: #333;
 | 
			
		||||
$border-color: #dadada;
 | 
			
		||||
$main-bg-color: white;
 | 
			
		||||
$secondary-text-color: white;
 | 
			
		||||
 | 
			
		||||
@import "_base.scss";
 | 
			
		||||
 | 
			
		||||
body.theme-crimson {
 | 
			
		||||
  @include baseTheme()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,7 +5,6 @@
 | 
			
		|||
	<meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
	<meta name='theme-color' content='#4169e1'>
 | 
			
		||||
 | 
			
		||||
	<link rel='stylesheet' href='/theme-default.css'>
 | 
			
		||||
	<link rel='stylesheet' href='/global.css'>
 | 
			
		||||
	<link rel='manifest' href='/manifest.json'>
 | 
			
		||||
	<link rel='icon' type='image/png' href='/favicon.png'>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue