mirror of
https://github.com/taobataoma/meanTorrent.git
synced 2026-07-31 18:51:16 +02:00
feat(forums): admin/Moderators and topic owner can edit topic title when click on the title text
#20
This commit is contained in:
@@ -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": {
|
||||
|
||||
@@ -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
|
||||
],
|
||||
|
||||
@@ -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
|
||||
]
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -950,6 +950,7 @@
|
||||
BTN_SAVE: '保存',
|
||||
BTN_CANCEL: '取消',
|
||||
LINK_EDIT: '编辑',
|
||||
CLICK_TO_EDIT: '单击修改',
|
||||
BTN_DELETE: '删除',
|
||||
BTN_SUBMIT_TOPIC: '提交话题',
|
||||
BTN_SUBMIT_REPLY: '提交回复',
|
||||
|
||||
125
modules/core/client/directives/editable-line.client.directive.js
Normal file
125
modules/core/client/directives/editable-line.client.directive.js
Normal 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 = ' ';
|
||||
|
||||
if (!$scope.readonly && ($scope.ngModel === '' || $scope.ngModel === undefined)) {
|
||||
$scope.div.addClass('editable-line-placeholder');
|
||||
if ($scope.placeHolder) {
|
||||
displayHtml = $scope.placeHolder;
|
||||
} else {
|
||||
displayHtml = ' ';
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}());
|
||||
22
modules/core/client/less/editable-line.less
Normal file
22
modules/core/client/less/editable-line.less
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -316,6 +316,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.topic-view-title {
|
||||
width: ~"calc(100% - 150px)";
|
||||
@media (max-width: @screen-sm-max) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* csslint ignore:end */
|
||||
|
||||
.reply-item {
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user