Skip to content
This repository has been archived by the owner on Mar 20, 2019. It is now read-only.

Commit

Permalink
#9 Add confirmation when closing a group
Browse files Browse the repository at this point in the history
  • Loading branch information
xiio authored and denschub committed May 25, 2016
1 parent 54b784e commit 526eab2
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 12 deletions.
6 changes: 6 additions & 0 deletions src/data/action_creators.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@ const ActionCreators = {
type: "TABGROUPS_RECEIVE",
tabgroups: tabgroups
};
},
setGroupCloseTimeout: function(timeout) {
return {
type: "GROUP_CLOSE_TIMEOUT_RECIEVE",
closeTimeout: timeout
};
}
};
22 changes: 22 additions & 0 deletions src/data/assets/css/groupspanel.css
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ ul, li {
top: 6px;
}

.group.closing .group-controls .group-close,
.group.closing:hover .group-controls .group-close,
.group.closing .group-controls .fa-chevron-down,
.group.closing .group-controls .group-edit {
display: none;
}

.group.closing .group-title {
color: #CCC;
text-decoration: line-through;
}

.group:hover .group-title {
padding-right: 55px;
}
Expand All @@ -130,3 +142,13 @@ ul, li {
.group:hover .group-controls .group-edit {
display: inline-block;
}

.group.closing .group-controls .group-close-undo-timer,
.group.closing .group-controls .group-close-undo {
color: #666;
}

.group.closing .group-controls:hover .group-close-undo-timer,
.group.closing .group-controls:hover .group-close-undo {
color: #000;
}
35 changes: 33 additions & 2 deletions src/data/components/group.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const Group = React.createClass({
propTypes: {
closeTimeout: React.PropTypes.number,
group: React.PropTypes.object.isRequired,
onGroupClick: React.PropTypes.func,
onGroupDrop: React.PropTypes.func,
Expand All @@ -13,6 +14,8 @@ const Group = React.createClass({

getInitialState: function() {
return {
closeTimer: this.props.closeTimeout,
closing: false,
editing: false,
expanded: false,
draggingOverCounter: 0,
Expand Down Expand Up @@ -54,6 +57,7 @@ const Group = React.createClass({
let groupClasses = classNames({
active: this.props.group.active,
editing: this.state.editing,
closing: this.state.closing,
draggingOver: this.state.draggingOverCounter !== 0,
dragSourceGroup: this.state.dragSourceGroup,
expanded: this.state.expanded,
Expand All @@ -78,13 +82,16 @@ const Group = React.createClass({
React.createElement(
GroupControls,
{
closeTimer: this.state.closeTimer,
closing: this.state.closing,
editing: this.state.editing,
expanded: this.state.expanded,
onClose: this.handleGroupCloseClick,
onEdit: this.handleGroupEditClick,
onEditAbort: this.handleGroupEditAbortClick,
onEditSave: this.handleGroupEditSaveClick,
onExpand: this.handleGroupExpandClick
onExpand: this.handleGroupExpandClick,
onUndoCloseClick: this.handleGroupCloseAbortClick
}
)
),
Expand All @@ -104,7 +111,24 @@ const Group = React.createClass({

handleGroupCloseClick: function(event) {
event.stopPropagation();
this.props.onGroupCloseClick(this.props.group.id);
this.setState({editing: false});
this.setState({closing: true});
this.setState({closeTimer: this.props.closeTimeout});

let group = this;

if (this.props.closeTimeout == 0) {
group.props.onGroupCloseClick(group.props.group.id);
return;
}

let timer = setInterval(function() {
group.setState({closeTimer: --group.state.closeTimer});
if (group.state.closeTimer <= 0) {
group.props.onGroupCloseClick(group.props.group.id);
clearInterval(timer);
}
}, 1000);
},

handleGroupClick: function(event) {
Expand Down Expand Up @@ -184,5 +208,12 @@ const Group = React.createClass({
}

return false;
},

handleGroupCloseAbortClick: function(event) {
event.stopPropagation();

this.setState({closing: false});
this.setState({closeTimer: this.props.closeTimeout});
}
});
38 changes: 32 additions & 6 deletions src/data/components/groupcontrols.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
const GroupControls = React.createClass({
propTypes: {
closeTimer: React.PropTypes.number,
expanded: React.PropTypes.bool.isRequired,
onClose: React.PropTypes.func,
onEdit: React.PropTypes.func,
onEditAbort: React.PropTypes.func,
onEditSave: React.PropTypes.func,
onExpand: React.PropTypes.func
onExpand: React.PropTypes.func,
onUndoCloseClick: React.PropTypes.func
},

render: function() {
let editControls;
getEditControls: function() {
let controls;
if (this.props.editing) {
editControls = [
controls = [
React.DOM.i({
className: "group-edit fa fa-fw fa-check",
onClick: this.props.onEditSave
Expand All @@ -22,12 +24,36 @@ const GroupControls = React.createClass({
})
];
} else {
editControls = React.DOM.i({
controls = React.DOM.i({
className: "group-edit fa fa-fw fa-pencil",
onClick: this.props.onEdit
});
}

return controls;
},

getClosingControls: function() {
return [
React.DOM.span(
{className: "group-close-undo-timer"},
this.props.closeTimer
),
React.DOM.i({
className: "group-close-undo fa fa-fw fa-undo",
onClick: this.props.onUndoCloseClick
})
];
},

render: function() {
let groupControls;
if (this.props.closing) {
groupControls = this.getClosingControls();
} else {
groupControls = this.getEditControls();
}

let expanderClasses = classNames({
"group-expand": true,
"fa": true,
Expand All @@ -40,7 +66,7 @@ const GroupControls = React.createClass({
{
className: "group-controls"
},
editControls,
groupControls,
React.DOM.i({
className: "group-close fa fa-fw fa-times",
onClick: this.props.onClose
Expand Down
5 changes: 4 additions & 1 deletion src/data/components/grouplist.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const GroupList = (() => {
const GroupListStandalone = React.createClass({
propTypes: {
groups: React.PropTypes.object.isRequired,
closeTimeout: React.PropTypes.number,
onGroupAddClick: React.PropTypes.func,
onGroupAddDrop: React.PropTypes.func,
onGroupClick: React.PropTypes.func,
Expand All @@ -25,6 +26,7 @@ const GroupList = (() => {
return React.createElement(Group, {
key: group.id,
group: group,
closeTimeout: this.props.closeTimeout,
onGroupClick: this.props.onGroupClick,
onGroupDrop: this.props.onGroupDrop,
onGroupCloseClick: this.props.onGroupCloseClick,
Expand All @@ -48,7 +50,8 @@ const GroupList = (() => {

return ReactRedux.connect((state) => {
return {
groups: state.get("tabgroups")
groups: state.get("tabgroups"),
closeTimeout: state.get("closeTimeout")
};
}, ActionCreators)(GroupListStandalone);
})();
4 changes: 4 additions & 0 deletions src/data/groupspanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ document.addEventListener("DOMContentLoaded", () => {
addon.port.on("Groups:Changed", (tabgroups) => {
store.dispatch(ActionCreators.setTabgroups(tabgroups));
});

addon.port.on("Groups:CloseTimeoutChanged", (timeout) => {
store.dispatch(ActionCreators.setGroupCloseTimeout(timeout));
});
6 changes: 4 additions & 2 deletions src/data/reducer.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
const INITIAL_STATE = Immutable.fromJS({
tabgroups: []
tabgroups: [],
closeTimeout: 0
});

const Reducer = function(state = INITIAL_STATE, action) {
switch (action.type) {
case "TABGROUPS_RECEIVE":
return state.set("tabgroups", Immutable.fromJS(action.tabgroups));
case "GROUP_CLOSE_TIMEOUT_RECIEVE":
return state.set("closeTimeout", action.closeTimeout);
}

return state;
};
36 changes: 35 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ TabGroups.prototype = {

bindEvents: function() {
this.bindHotkeyPreference();
this.bindGroupPreference();
this.bindPanelButtonEvents();
this.bindPanelEvents();
this.bindTabEvents();
Expand All @@ -50,7 +51,8 @@ TabGroups.prototype = {
l10n: Utils.getL10nStrings([
"add_group",
"unnamed_group"
])
]),
groupCloseTimeout: Prefs.prefs.groupCloseTimeout
}
});
},
Expand Down Expand Up @@ -161,6 +163,16 @@ TabGroups.prototype = {
});
},

bindGroupPreference: function() {
let emitCloseTimeoutChange = () => {
this._groupsPanel.port.emit("Groups:CloseTimeoutChanged", Prefs.prefs.groupCloseTimeout);
};

Prefs.on("groupCloseTimeout", emitCloseTimeoutChange);

emitCloseTimeoutChange();
},

bindPanelButtonEvents: function() {
this._panelButton.on("change", (state) => {
if (!state.checked) {
Expand Down Expand Up @@ -231,6 +243,21 @@ TabGroups.prototype = {
},

onGroupClose: function(event) {
let groupTabCount = this._tabs.getGroupTabCount(
this._getTabBrowser(),
event.groupID
);

if (groupTabCount > 0) {
let closeGroupConfirmed = this._closeGroupConfirmation();

this._groupsPanel.show({position: this._panelButton});

if (!closeGroupConfirmed) {
return;
}
}

this._tabs.closeGroup(
this._getWindow(),
this._getTabBrowser(),
Expand Down Expand Up @@ -283,6 +310,13 @@ TabGroups.prototype = {

_getTabBrowser: function() {
return TabsUtils.getTabBrowser(this._getWindow());
},

_closeGroupConfirmation: function() {
let promptTitle = _("close_group_prompt_title");
let promptMessage = _("close_group_prompt_message");

return Utils.confirm(promptTitle, promptMessage);
}
};

Expand Down
4 changes: 4 additions & 0 deletions src/lib/tabmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ TabManager.prototype = {
return recentlyAddedGroup;
},

getGroupTabCount: function(tabBrowser, groupID) {
return this._storage.getTabIndexesByGroup(tabBrowser, groupID).length;
},

/**
* Closes a group and all attached tabs
*
Expand Down
15 changes: 15 additions & 0 deletions src/lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const _ = require("sdk/l10n").get;
const PrefService = require("sdk/preferences/service");
const {Cc, Ci} = require("chrome");

/**
* Returns an object of translated strings for the use in the frontend.
Expand Down Expand Up @@ -37,3 +38,17 @@ exports.themeSwitch = function(object) {

return retValue;
};

/**
* Confirm prompt service.
*
* @param {String} title - title of confirm prompt
* @param {String} message - question
* @returns {boolean} TRUE if user confirm, FALSE otherwise
*/
exports.confirm = function(title, message) {
let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Ci.nsIPromptService);

return prompts.confirm(null, title, message);
};
6 changes: 6 additions & 0 deletions src/locale/en-US.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
bindPanoramaShortcut_title = Listen to Ctrl/Cmd-Shift-E
enableAlphabeticSort_title = Enable alphabetic sorting
groupUndoCloseTimeout_title = Closing group timeout
groupUndoCloseTimeout_description = Delay before close group in seconds

add_group = Create new group
close_group_prompt_title = Close group
close_group_prompt_message = Do you want to close this group?
panelButton_label = Group Tabs
unnamed_group = Unnamed Group
close_group_prompt_title = Close group
close_group_prompt_message = Do you want to close this group?
6 changes: 6 additions & 0 deletions src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
"title": "Enable alphabetic sorting",
"type": "bool",
"value": false
},
{
"name": "groupCloseTimeout",
"title": "Closing group timeout",
"type": "integer",
"value": 0
}
]
}

0 comments on commit 526eab2

Please sign in to comment.