feat(forums): admin/Moderators and topic owner can edit topic title when click on the title text

#20
This commit is contained in:
OldHawk
2017-12-07 17:47:05 +08:00
parent 7c1c1558dd
commit c38b35b707
11 changed files with 184 additions and 4 deletions

View File

@@ -34,7 +34,8 @@
"angular-side-overlay": "^1.0.3",
"bootstrap-markdown": "^2.10.0",
"font-awesome": "^4.7.0",
"ngprogress": "^1.1.3"
"ngprogress": "^1.1.3",
"jquery-awesome-cursor": "^0.3.1"
},
"overrides": {
"bootstrap": {

View File

@@ -74,7 +74,9 @@ module.exports = {
'public/lib/bootstrap-markdown/js/bootstrap-markdown.js',
'public/lib/bootstrap-markdown/locale/bootstrap-markdown.zh.js',
//ngProgress
'public/lib/ngprogress/build/ngprogress.js'
'public/lib/ngprogress/build/ngprogress.js',
//jquery-awesome-cursor
'public/lib/jquery-awesome-cursor/dist/jquery.awesome-cursor.js'
// endbower
],

View File

@@ -74,7 +74,9 @@ module.exports = {
'public/lib/bootstrap-markdown/js/bootstrap-markdown.js',
'public/lib/bootstrap-markdown/locale/bootstrap-markdown.zh.js',
//ngProgress
'public/lib/ngprogress/build/ngprogress.min.js'
'public/lib/ngprogress/build/ngprogress.min.js',
//jquery-awesome-cursor
'public/lib/jquery-awesome-cursor/dist/jquery.awesome-cursor.min.js'
// endbower
]

View File

@@ -950,6 +950,7 @@
BTN_SAVE: 'Save',
BTN_CANCEL: 'Cancel',
LINK_EDIT: 'Edit',
CLICK_TO_EDIT: 'Click to edit',
BTN_DELETE: 'Delete',
BTN_SUBMIT_TOPIC: 'Submit New Topic',
BTN_SUBMIT_REPLY: 'Submit New Reply',

View File

@@ -950,6 +950,7 @@
BTN_SAVE: '保存',
BTN_CANCEL: '取消',
LINK_EDIT: '编辑',
CLICK_TO_EDIT: '单击修改',
BTN_DELETE: '删除',
BTN_SUBMIT_TOPIC: '提交话题',
BTN_SUBMIT_REPLY: '提交回复',

View File

@@ -0,0 +1,125 @@
(function () {
'use strict';
angular.module('core')
.directive('editableLine', editableLine);
editableLine.$inject = [];
function editableLine() {
var highlightColor = 'transparent';
return {
restrict: 'A',
require: '^ngModel',
scope: {
ngModel: '=ngModel',
callback: '=',
callbackParameter: '=',
linkCallback: '=',
readonly: '=',
placeHolder: '@'
},
template: '<input ng-model="ngModel" class="editable-line editable-line-input"><span class="editable-line editable-line-display" title="{{ \'FORUMS.CLICK_TO_EDIT\' | translate}}"></span>',
link: function ($scope, $element, $attr) {
$scope.div = jQuery($element).find('.editable-line-display');
$scope.input = jQuery($element).find('.editable-line-input');
$scope.originalDivBackground = $scope.div.css('background-color');
$scope.div.awesomeCursor('wrench', {
color: '#ff6000',
flip: 'horizontal',
outline: '#ff3e00'
});
var originalValue;
$scope.div.bind('click', function () {
if ($scope.readonly) {
return;
}
originalValue = $scope.ngModel;
// get the cursor offset from display DIV
var sel = window.getSelection();
var offset = sel.focusOffset;
// hide DIV and show INPUT
$scope.div.css('display', 'none');
$scope.input.css('display', 'block');
$scope.input.focus();
// Move cursor to the same offset
var node = $scope.input.get(0);
node.setSelectionRange(offset, offset);
});
$scope.input.bind('blur', function () {
if ($scope.callback) {
if (!$scope.ngModel) {
$scope.ngModel = originalValue;
$scope.$apply();
}
if ($scope.callbackParameter !== undefined) {
$scope.callback($scope.ngModel !== originalValue, $scope.callbackParameter);
} else {
$scope.callback($scope.ngModel !== originalValue);
}
}
$scope.div.css('display', 'block');
$scope.input.css('display', 'none');
$scope.refresh();
});
$scope.div.bind('mouseover', function () {
if ($scope.readonly) {
return;
}
$scope.div.css('background-color', highlightColor);
});
$scope.div.bind('mouseout', function () {
$scope.div.css('background-color', ''); // Removing CSS from DIV
});
$element.bind('keydown', function (event) {
if (event.which === 13) {
event.target.blur();
} else if (event.which === 27) {
// ESC key
$scope.ngModel = originalValue;
$scope.$apply();
event.target.blur();
}
});
$scope.refresh = function () {
var linkify = false;
var displayHtml = '&nbsp;';
if (!$scope.readonly && ($scope.ngModel === '' || $scope.ngModel === undefined)) {
$scope.div.addClass('editable-line-placeholder');
if ($scope.placeHolder) {
displayHtml = $scope.placeHolder;
} else {
displayHtml = '&nbsp;';
}
} else {
$scope.div.removeClass('editable-line-placeholder');
if ($scope.linkCallback) {
displayHtml = '<a class="generated-link" target="_blank" href="' + $scope.linkCallback($scope.ngModel) + '">' + $scope.ngModel + '</a>';
} else {
displayHtml = $scope.ngModel;
}
}
$scope.div.html(displayHtml);
if ($scope.linkCallback) {
$scope.div.find('a.generated-link').click(function (e) {
e.stopPropagation();
});
}
};
$scope.$watch('ngModel', $scope.refresh);
// initialize
$scope.input.css('display', 'none');
$scope.input.css('background', highlightColor);
}
};
}
}());

View File

@@ -0,0 +1,22 @@
@import (reference) "mt-var.less";
.editable-line {
padding: 0;
margin: 0;
width: 100%;
word-wrap: break-word;
white-space: nowrap;
&:focus {
border: 1px dotted #ccc;
}
}
.editable-line-display {
overflow: hidden;
text-overflow: ellipsis;
}
.editable-line-placeholder {
color: #888888;
background-color: transparent;
}

View File

@@ -189,6 +189,21 @@
}
};
/**
* onTopicTitleEdited
*/
$scope.onTopicTitleEdited = function (modifyed) {
console.log(modifyed);
if (vm.topic && modifyed) {
vm.topic.$update(function (res) {
vm.topic = res;
NotifycationService.showSuccessNotify('FORUMS.TOPIC_EDIT_SUCCESSFULLY');
}, function (res) {
NotifycationService.showErrorNotify(res.data.message, 'FORUMS.TOPIC_EDIT_FAILED');
});
}
};
/**
* beginEditTopic
* @param t

View File

@@ -316,6 +316,13 @@
}
}
.topic-view-title {
width: ~"calc(100% - 150px)";
@media (max-width: @screen-sm-max) {
width: 100%;
}
}
/* csslint ignore:end */
.reply-item {

View File

@@ -49,7 +49,10 @@
<thead>
<tr>
<th>
<div class="text-long"><span>{{vm.topic.title}}</span></div>
<!--<div class="text-long"><span>{{vm.topic.title}}</span></div>-->
<div class="topic-view-title text-long">
<span editable-line readonly="!vm.canEdit() && !vm.isOwner(vm.topic)" ng-model="vm.topic.title" callback="onTopicTitleEdited"></span>
</div>
<div class="count-info xs-hide sm-hide">
<span>{{'FORUMS.FIELDS.VIEWS' | translate}}: {{vm.topic.viewCount}}</span>,

View File

@@ -456,6 +456,7 @@ exports.updateTopic = function (req, res) {
});
}
topic.title = req.body.title;
topic.content = req.body.content;
topic.updatedAt = Date.now();
topic.updatedBy = req.user;