diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b7a672f4e70..20a8ab48ee1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ All notable changes to this project will be documented in this file. ### Added - Stats API [currently in beta] plausible/analytics#679 -- 30 day and 6 month keybindings (`3` and `6`, respectively) plausible/analytics#709 +- 30 day and 6 month keybindings (`T` and `S`, respectively) plausible/analytics#709 +- Site switching keybinds (1-9 for respective sites) plausible/analytics#735 ### Fixed - Capitalized date/time selection keybinds not working plausible/analytics#709 diff --git a/assets/js/dashboard/datepicker.js b/assets/js/dashboard/datepicker.js index cffd538e8374..8ba6bdf4f0d2 100644 --- a/assets/js/dashboard/datepicker.js +++ b/assets/js/dashboard/datepicker.js @@ -100,7 +100,7 @@ class DatePicker extends React.Component { this.setState({open: false}); - const keys = ['d', 'r', 'w', 'm', 'y', '3', '6']; + const keys = ['d', 'r', 'w', 'm', 'y', 't', 's']; const redirects = [{date: false, period: 'day'}, {period: 'realtime'}, {date: false, period: '7d'}, {date: false, period: 'month'}, {date: false, period: '12mo'}, {date: false, period: '30d'}, {date: false, period: '6mo'}]; if (keys.includes(e.key.toLowerCase())) { @@ -302,8 +302,8 @@ class DatePicker extends React.Component { 'Last 7 days': 'W', 'Month to Date': 'M', 'Last 12 months': 'Y', - 'Last 6 months': '6', - 'Last 30 days': '3', + 'Last 6 months': 'S', + 'Last 30 days': 'T', }; return ( diff --git a/assets/js/dashboard/site-switcher.js b/assets/js/dashboard/site-switcher.js index 4b362d0edaf2..3a4d792c8b3f 100644 --- a/assets/js/dashboard/site-switcher.js +++ b/assets/js/dashboard/site-switcher.js @@ -5,6 +5,8 @@ export default class SiteSwitcher extends React.Component { constructor() { super() this.handleClick = this.handleClick.bind(this) + this.handleKeydown = this.handleKeydown.bind(this); + this.populateSites = this.populateSites.bind(this); this.state = { open: false, sites: null, @@ -14,13 +16,26 @@ export default class SiteSwitcher extends React.Component { } componentDidMount() { + this.populateSites(); + document.addEventListener("keydown", this.handleKeydown); document.addEventListener('mousedown', this.handleClick, false); } componentWillUnmount() { + document.removeEventListener("keydown", this.handleKeydown); document.removeEventListener('mousedown', this.handleClick, false); } + populateSites() { + fetch('/api/sites') + .then( response => { + if (!response.ok) { throw response } + return response.json() + }) + .then((sites) => this.setState({loading: false, sites: sites})) + .catch((e) => this.setState({loading: false, error: e})) + } + handleClick(e) { if (this.dropDownNode && this.dropDownNode.contains(e.target)) return; if (!this.state.open) return; @@ -28,28 +43,39 @@ export default class SiteSwitcher extends React.Component { this.setState({open: false}) } + handleKeydown(e) { + const { query, history, site } = this.props; + const { sites } = this.state; + + if (e.ctrlKey || e.metaKey || e.altKey || e.isComposing || e.keyCode === 229 || !sites) return + + const siteNum = parseInt(e.key) + + if (1 <= siteNum <= 9 && siteNum <= sites.length && sites[siteNum-1] !== site.domain) { + window.location = `/${encodeURIComponent(sites[siteNum-1])}` + } + + } + toggle() { if (!this.props.loggedIn) return; this.setState({open: !this.state.open}) if (!this.state.sites) { - fetch('/api/sites') - .then( response => { - if (!response.ok) { throw response } - return response.json() - }) - .then((sites) => this.setState({loading: false, sites: sites})) - .catch((e) => this.setState({loading: false, error: e})) + this.populateSites(); } } - renderSiteLink(domain) { + renderSiteLink(domain, index) { const extraClass = domain === this.props.site.domain ? 'font-medium text-gray-900 dark:text-gray-100 cursor-default font-bold' : 'hover:bg-gray-100 dark:hover:bg-gray-900 hover:text-gray-900 dark:hover:text-gray-100 focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-900 focus:text-gray-900 dark:focus:text-gray-100' return ( - - - {domain} + + + + {domain} + + {index < 9 && {index+1}} ) } @@ -75,7 +101,7 @@ export default class SiteSwitcher extends React.Component {