Skip to content

Commit

Permalink
Implemented monitor normalization UI, added React DevTools
Browse files Browse the repository at this point in the history
  • Loading branch information
xanderfrangos committed Aug 24, 2019
1 parent 77cbb0c commit adfd1fe
Show file tree
Hide file tree
Showing 13 changed files with 464 additions and 210 deletions.
1 change: 1 addition & 0 deletions index.html
Expand Up @@ -12,6 +12,7 @@
/>
<link rel="stylesheet" href="./src/css/vars.scss" />
<link rel="stylesheet" href="./src/css/panel.scss" />
<link rel="stylesheet" href="./src/css/slider.scss" />
</head>
<body>
<div id="root"></div>
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -60,6 +60,7 @@
"cross-env": "5.2.0",
"electron": "6.0.1",
"electron-builder": "20.38.4",
"electron-react-devtools": "^0.5.3",
"electron-rebuild": "^1.8.5",
"parcel-bundler": "1.12.3",
"sass": "^1.22.9",
Expand Down
1 change: 1 addition & 0 deletions settings.html
Expand Up @@ -9,6 +9,7 @@
<link rel="shortcut icon" href="./src/assets/logo.ico" type="image/x-icon" />
<link rel="stylesheet" href="./src/css/vars.scss" />
<link rel="stylesheet" href="./src/css/page.scss" />
<link rel="stylesheet" href="./src/css/slider.scss" />
</head>

<body>
Expand Down
24 changes: 24 additions & 0 deletions src/components/BrightnessPanel.jsx
Expand Up @@ -93,6 +93,27 @@ recievedMonitors = (e) => {
this.forceUpdate()
}


updateMinMax = () => {
if(this.state.monitors.length > 0) {

let newMonitors = Object.assign(this.state.monitors, {})

for(let monitor of newMonitors) {
for(let remap in this.state.remaps) {
if(monitor.name == remap) {
monitor.min = this.state.remaps[remap].min
monitor.max = this.state.remaps[remap].max
}
}
}

this.setState({
monitors: newMonitors
})
}
}

// Update monitor names
recievedNames = (e) => {
if(this.state.monitors.length > 0) {
Expand Down Expand Up @@ -133,7 +154,10 @@ recievedSettings = (e) => {
updateInterval
}, () => {
this.resetBrightnessInterval()
this.updateMinMax()
this.forceUpdate()
})

}


Expand Down
262 changes: 210 additions & 52 deletions src/components/SettingsWindow.jsx
@@ -1,6 +1,7 @@
import React, { PureComponent, useState } from "react";
import Titlebar from './Titlebar'
import Monitor from './SettingsMonitor'
import Slider from "./Slider";


export default class SettingsWindow extends PureComponent {
Expand All @@ -11,26 +12,20 @@ export default class SettingsWindow extends PureComponent {
this.state = {
theme: 'default',
openAtLogin: false,
monitors: []
monitors: [],
remaps: {}
}
this.lastLevels = []
}

componentDidMount() {
window.addEventListener("monitorsUpdated", (e) => {
this.setState({
monitors: window.allMonitors
})
this.forceUpdate()
})
window.addEventListener("namessUpdated", (e) => {
this.setState({
monitors: window.allMonitors
})
this.forceUpdate()
})
window.addEventListener("monitorsUpdated", this.recievedMonitors)
window.addEventListener("namesUpdated", this.recievedNames)

window.addEventListener("settingsUpdated", (e) => {
this.forceUpdate()
})

fetch("https://api.github.com/repos/xanderfrangos/twinkle-tray/releases").then((response) => { response.json().then( (json) => {
this.setState({
releaseURL: json[0].html_url,
Expand All @@ -39,6 +34,76 @@ export default class SettingsWindow extends PureComponent {
})});
}

getRemap = (name) => {
if(this.state.remaps[name] === undefined) {
return {
min: 0,
max: 100
}
}
return this.state.remaps[name]
}


minMaxChanged = (value, slider) => {

const name = slider.props.monitorName
const remaps = Object.assign(this.state.remaps, {})

if(remaps[name] === undefined) {
remaps[name] = {
min: 0,
max: 100
}
}

if(slider.props.type == "min") {
remaps[name].min = value


// Keep within 10%, cap

if(remaps[name].min > remaps[name].max - 10) {
remaps[name].max = remaps[name].min + 10
}

if(remaps[name].max > 100) {
remaps[name].max = 100
}

if(remaps[name].min > remaps[name].max - 10) {
remaps[name].min = remaps[name].max - 10
}

} else if(slider.props.type == "max") {
remaps[name].max = value

// Keep within 10%, cap

if(remaps[name].min > remaps[name].max - 10) {
remaps[name].min = remaps[name].max - 10
}

if(remaps[name].min < 0) {
remaps[name].min = 0
}

if(remaps[name].min > remaps[name].max - 10) {
remaps[name].max = remaps[name].min + 10
}

}


this.setState({
remaps
})

this.forceUpdate()
window.sendSettings({ remaps: remaps })
window.requestSettings()
}

themeChanged = (event) => {
this.setState({ theme: event.target.value })
window.sendSettings({ theme: event.target.value })
Expand All @@ -51,7 +116,6 @@ export default class SettingsWindow extends PureComponent {

startupChanged = (event) => {
const openAtLogin = (this.state.openAtLogin ? false : true)
console.log(openAtLogin)
this.setState({ openAtLogin })
window.sendSettings({ openAtLogin })
}
Expand All @@ -72,55 +136,149 @@ export default class SettingsWindow extends PureComponent {
}
}

getMinMaxMonitors = () => {
if(this.state.monitors == undefined || this.state.monitors.length == 0) {
return (<div className="no-displays-message">No displays found.<br /><br /></div>)
} else {
return this.state.monitors.map((monitor, index) => {
const remap = this.getRemap(monitor.name)
return (
<div key={monitor.name}>
<br />
<div className="sectionSubtitle"><div className="icon">&#xE7F4;</div><div>{ monitor.name }</div></div>
<label>Min</label>
<Slider key={monitor.name + ".min"} type="min" monitorNum={index} level={remap.min} monitorName={ monitor.name } onChange={this.minMaxChanged} />
<label>Max</label>
<Slider key={monitor.name + ".max"} type="max" monitorNum={index} level={remap.max} monitorName={ monitor.name } onChange={this.minMaxChanged} />
</div>

)
} )
}
}

getMonitors = () => {
getRenameMonitors = () => {
if(this.state.monitors == undefined || this.state.monitors.length == 0) {
return (<div className="no-displays-message">No displays found.</div>)
} else {
return this.state.monitors.map((monitor, index) => (
<Monitor key={index} monitorNum={index} name={monitor.name} level={monitor.brightness} lastUpdate={this.props.lastUpdate} />
))
return (<div className="no-displays-message">No displays found.<br /><br /></div>)
} else {
return this.state.monitors.map((monitor, index) => (
<div key={index}>
<br />
<div className="sectionSubtitle"><div className="icon">&#xE7F4;</div><div>{ monitor.name }</div></div>
<input type="text" placeholder="Enter name"></input>
</div>

))
}
}







// Update monitor info
recievedMonitors = (e) => {
if(this.state.monitors.length > 0 || e.detail.length > 0) {

let idx = 0
let newMonitors = Object.assign(e.detail, {})

this.lastLevels.length = e.detail.length

for(let monitor of this.state.monitors) {
newMonitors[idx] = Object.assign(newMonitors[idx], { name: monitor.name, min: monitor.min, max: monitor.max })
idx++
}

this.setState({
monitors: newMonitors
})
}

this.forceUpdate()
}

// Update monitor names
recievedNames = (e) => {
if(this.state.monitors.length > 0) {

let idx = 0
let newMonitors = Object.assign(this.state.monitors, {})

for(let monitor of e.detail) {
newMonitors[idx] = Object.assign(newMonitors[idx], { name: monitor.name })

for(let remap in this.state.remaps) {
if(monitor.name == remap) {
newMonitors[idx].min = this.state.remaps[remap].min
newMonitors[idx].max = this.state.remaps[remap].max
}
}

idx++
}

this.setState({
monitors: newMonitors
})
}

this.forceUpdate()
}






render() {
return (
<div className="window-base" data-theme={window.settings.theme || "default"}>
<Titlebar title="Twinkle Tray Settings" />
<div className="pageSection">
<div className="sectionTitle">General</div>
<label>Launch at startup</label>
<input onChange={this.startupChanged} checked={window.settings.openAtLogin || false} data-checked={window.settings.openAtLogin || false} type="checkbox" id="theme" />
<label>App Theme</label>
<select value={window.settings.theme} onChange={this.themeChanged}>
<option value="default">System Preference (Default)</option>
<option value="dark">Dark Mode</option>
<option value="light">Light Mode</option>
</select>
<label>Brightness update rate</label>
<select value={window.settings.updateInterval} onChange={this.updateIntervalChanged}>
<option value="250">Fast (0.25s)</option>
<option value="500">Normal (0.5s)</option>
<option value="1000">Slow (1s)</option>
<option value="2000">Very Slow (2s)</option>
</select>
</div>
<div className="pageSection" style={{display:'block'}}>
<div className="sectionTitle">Monitors</div>
<p>Give monitors different names, or remap the min/max brightness so that the levels across all monitors are normalized.</p>

{ this.getMonitors() }

<div>
<label>Rename</label>
<input type="text" />
<div id="page">
<div className="pageSection">
<div className="sectionTitle">General</div>
<label>Launch at startup</label>
<input onChange={this.startupChanged} checked={window.settings.openAtLogin || false} data-checked={window.settings.openAtLogin || false} type="checkbox" id="theme" />
<label>App Theme</label>
<select value={window.settings.theme} onChange={this.themeChanged}>
<option value="default">System Preference (Default)</option>
<option value="dark">Dark Mode</option>
<option value="light">Light Mode</option>
</select>
<label>Brightness update rate</label>
<p>How often the brightness will be updated on your displays as you're adjusting their values. Increase the time if your displays are flickering.</p>
<select value={window.settings.updateInterval} onChange={this.updateIntervalChanged}>
<option value="250">Fast (0.25s)</option>
<option value="500">Normal (0.5s)</option>
<option value="1000">Slow (1s)</option>
<option value="2000">Very Slow (2s)</option>
</select>
</div>
<div className="pageSection">
<div className="sectionTitle">Normalize Brightness</div>
<p>Monitors often have different brightness ranges. By limiting the minimum/maximum brightness per display, the brightness levels between displays is much more consistent.</p>
<br />
<a className="button" onClick={ () => {} }>Run normalization assistant</a>
<br /><br />
<div style={{ maxWidth: "320px" }}>
{ this.getMinMaxMonitors() }
</div>
</div>
<div className="pageSection" style={{display:'block'}}>
<div className="sectionTitle">Rename Monitors</div>
<p>If you'd prefer a different name for each monitor (ex "Left Monitor", "Middle Monitor"), you can enter it below. Leaving the field empty will restore the original name.</p>

{ this.getRenameMonitors() }

</div>
<div className="pageSection">
<div className="sectionTitle">Updates</div>
<p>Your version of Twinkle Tray is <b>{window.version || "not available"}</b>.</p>
{ this.getUpdate() }
</div>
</div>
<div className="pageSection">
<div className="sectionTitle">Updates</div>
<p>Your version of Twinkle Tray is <b>{window.version || "not available"}</b>.</p>
{ this.getUpdate() }
</div>
</div>

Expand Down

0 comments on commit adfd1fe

Please sign in to comment.