@@ -46,22 +46,28 @@ export default class StatusList extends ImmutablePureComponent { | |||
handleMoveUp = (id, featured) => { | |||
const elementIndex = this.getCurrentStatusIndex(id, featured) - 1; | |||
this._selectChild(elementIndex); | |||
this._selectChild(elementIndex, true); | |||
} | |||
handleMoveDown = (id, featured) => { | |||
const elementIndex = this.getCurrentStatusIndex(id, featured) + 1; | |||
this._selectChild(elementIndex); | |||
this._selectChild(elementIndex, false); | |||
} | |||
handleLoadOlder = debounce(() => { | |||
this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined); | |||
}, 300, { leading: true }) | |||
_selectChild (index) { | |||
const element = this.node.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`); | |||
_selectChild (index, align_top) { | |||
const container = this.node.node; | |||
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`); | |||
if (element) { | |||
if (align_top && container.scrollTop > element.offsetTop) { | |||
element.scrollIntoView(true); | |||
} else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) { | |||
element.scrollIntoView(false); | |||
} | |||
element.focus(); | |||
} | |||
} | |||
@@ -20,18 +20,24 @@ export default class ConversationsList extends ImmutablePureComponent { | |||
handleMoveUp = id => { | |||
const elementIndex = this.getCurrentIndex(id) - 1; | |||
this._selectChild(elementIndex); | |||
this._selectChild(elementIndex, true); | |||
} | |||
handleMoveDown = id => { | |||
const elementIndex = this.getCurrentIndex(id) + 1; | |||
this._selectChild(elementIndex); | |||
this._selectChild(elementIndex, false); | |||
} | |||
_selectChild (index) { | |||
const element = this.node.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`); | |||
_selectChild (index, align_top) { | |||
const container = this.node.node; | |||
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`); | |||
if (element) { | |||
if (align_top && container.scrollTop > element.offsetTop) { | |||
element.scrollIntoView(true); | |||
} else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) { | |||
element.scrollIntoView(false); | |||
} | |||
element.focus(); | |||
} | |||
} | |||
@@ -113,18 +113,24 @@ class Notifications extends React.PureComponent { | |||
handleMoveUp = id => { | |||
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1; | |||
this._selectChild(elementIndex); | |||
this._selectChild(elementIndex, true); | |||
} | |||
handleMoveDown = id => { | |||
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1; | |||
this._selectChild(elementIndex); | |||
this._selectChild(elementIndex, false); | |||
} | |||
_selectChild (index) { | |||
const element = this.column.node.querySelector(`article:nth-of-type(${index + 1}) .focusable`); | |||
_selectChild (index, align_top) { | |||
const container = this.column.node; | |||
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`); | |||
if (element) { | |||
if (align_top && container.scrollTop > element.offsetTop) { | |||
element.scrollIntoView(true); | |||
} else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) { | |||
element.scrollIntoView(false); | |||
} | |||
element.focus(); | |||
} | |||
} | |||
@@ -316,15 +316,15 @@ class Status extends ImmutablePureComponent { | |||
const { status, ancestorsIds, descendantsIds } = this.props; | |||
if (id === status.get('id')) { | |||
this._selectChild(ancestorsIds.size - 1); | |||
this._selectChild(ancestorsIds.size - 1, true); | |||
} else { | |||
let index = ancestorsIds.indexOf(id); | |||
if (index === -1) { | |||
index = descendantsIds.indexOf(id); | |||
this._selectChild(ancestorsIds.size + index); | |||
this._selectChild(ancestorsIds.size + index, true); | |||
} else { | |||
this._selectChild(index - 1); | |||
this._selectChild(index - 1, true); | |||
} | |||
} | |||
} | |||
@@ -333,23 +333,29 @@ class Status extends ImmutablePureComponent { | |||
const { status, ancestorsIds, descendantsIds } = this.props; | |||
if (id === status.get('id')) { | |||
this._selectChild(ancestorsIds.size + 1); | |||
this._selectChild(ancestorsIds.size + 1, false); | |||
} else { | |||
let index = ancestorsIds.indexOf(id); | |||
if (index === -1) { | |||
index = descendantsIds.indexOf(id); | |||
this._selectChild(ancestorsIds.size + index + 2); | |||
this._selectChild(ancestorsIds.size + index + 2, false); | |||
} else { | |||
this._selectChild(index + 1); | |||
this._selectChild(index + 1, false); | |||
} | |||
} | |||
} | |||
_selectChild (index) { | |||
const element = this.node.querySelectorAll('.focusable')[index]; | |||
_selectChild (index, align_top) { | |||
const container = this.node; | |||
const element = container.querySelectorAll('.focusable')[index]; | |||
if (element) { | |||
if (align_top && container.scrollTop > element.offsetTop) { | |||
element.scrollIntoView(true); | |||
} else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) { | |||
element.scrollIntoView(false); | |||
} | |||
element.focus(); | |||
} | |||
} | |||
@@ -367,11 +367,16 @@ class UI extends React.PureComponent { | |||
handleHotkeyFocusColumn = e => { | |||
const index = (e.key * 1) + 1; // First child is drawer, skip that | |||
const column = this.node.querySelector(`.column:nth-child(${index})`); | |||
if (!column) return; | |||
const container = column.querySelector('.scrollable'); | |||
if (column) { | |||
const status = column.querySelector('.focusable'); | |||
if (container) { | |||
const status = container.querySelector('.focusable'); | |||
if (status) { | |||
if (container.scrollTop > status.offsetTop) { | |||
status.scrollIntoView(true); | |||
} | |||
status.focus(); | |||
} | |||
} | |||