Merge branch 'master-redesign' into master-redesign-templates-and-blog

This commit is contained in:
Henry Oswald 2014-07-04 13:06:47 +01:00
commit 86a9d08e5c
32 changed files with 446 additions and 201 deletions

View file

@ -33,6 +33,14 @@ block content
.alert.alert-warning.small(ng-if="connection.reconnecting")
strong Reconnecting...
.div(ng-controller="SavingNotificationController")
.alert.alert-warning.small(
ng-repeat="(doc_id, state) in docSavingStatus"
ng-if="state.unsavedSeconds > 3"
)
| Saving {{ state.doc.name }}... ({{ state.unsavedSeconds }} seconds of unsaved changes)
include ./editor/left-menu
#chat-wrapper(
@ -56,11 +64,23 @@ block content
.ui-layout-center
include ./editor/editor
include ./editor/binary-file
include ./editor/track-changes
.ui-layout-east
include ./editor/chat
script(type="text/ng-template", id="genericMessageModalTemplate")
.modal-header
button.close(
type="button"
data-dismiss="modal"
ng-click="done()"
) ×
h3 {{ title }}
.modal-body {{ message }}
.modal-footer
button.btn.btn-info(ng-click="done()") OK
script(src='/socket.io/socket.io.js')

View file

@ -0,0 +1,19 @@
div.binary-file.full-size(
ng-controller="BinaryFileController"
ng-show="ui.view == 'file'"
ng-if="openFile"
)
img(
ng-src="/project/{{ project_id }}/file/{{ openFile.id }}"
ng-if="['png', 'jpg', 'jpeg', 'gif'].indexOf(extension(openFile)) > -1"
)
img(
ng-src="/project/{{ project_id }}/file/{{ openFile.id }}?format=png"
ng-if="['pdf', 'eps'].indexOf(extension(openFile)) > -1"
)
p.no-preview(
ng-if="['png', 'jpg', 'jpeg', 'gif', 'pdf', 'eps'].indexOf(extension(openFile)) == -1"
) Sorry, no preview is available.
a.btn.btn-info(
ng-href="/project/{{ project_id }}/file/{{ openFile.id }}"
) Download {{ openFile.name }}

View file

@ -25,7 +25,8 @@ div.full-size(
cursor-position="editor.cursorPosition",
goto-line="editor.gotoLine",
resize-on="layout:main:resize,layout:pdf:resize",
annotations="pdf.logEntryAnnotations[editor.open_doc_id]"
annotations="pdf.logEntryAnnotations[editor.open_doc_id]",
read-only="!permissions.write"
)
.ui-layout-east

View file

@ -1,5 +1,5 @@
aside#file-tree(ng-controller="FileTreeController")
.toolbar.toolbar-small
.toolbar.toolbar-small(ng-if="permissions.write")
a(
href,
ng-click="openNewDocModal()",
@ -39,10 +39,19 @@ aside#file-tree(ng-controller="FileTreeController")
)
i.fa.fa-trash-o
.file-tree-inner
ul.list-unstyled.file-tree-list
.file-tree-inner(
ng-if="rootFolder",
ng-controller="FileTreeRootFolderController",
ng-class="{ 'no-toolbar': !permissions.write }"
)
ul.list-unstyled.file-tree-list(
droppable="permissions.write"
accept=".entity-name"
on-drop-callback="onDrop"
)
file-entity(
entity="entity",
permissions="permissions",
ng-repeat="entity in rootFolder.children | orderBy:[orderByFoldersFirst, 'name']"
)
@ -72,11 +81,12 @@ script(type='text/ng-template', id='entityListItemTemplate')
.entity(ng-if="entity.type != 'folder'")
.entity-name(
ng-click="select()"
ng-dblclick="startRenaming()"
draggable
ng-dblclick="permissions.write && startRenaming()"
draggable="permissions.write"
context-menu
data-target="context-menu-{{ entity.id }}"
context-menu-container="body"
context-menu-disabled="!permissions.write"
)
//- Just a spacer to align with folders
i.fa.fa-fw.toggle(ng-if="entity.type != 'folder'")
@ -88,6 +98,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
ng-hide="entity.renaming"
) {{ entity.name }}
input(
ng-if="permissions.write",
ng-show="entity.renaming",
ng-model="inputs.name",
ng-blur="finishRenaming()",
@ -95,7 +106,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
on-enter="finishRenaming()"
)
span.dropdown(ng-show="entity.selected")
span.dropdown(
ng-show="entity.selected",
ng-if="permissions.write"
)
a.dropdown-toggle(href)
i.fa.fa-chevron-down
@ -113,7 +127,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
ng-click="openDeleteModal()"
) Delete
div.dropdown.context-menu(id="context-menu-{{ entity.id }}")
div.dropdown.context-menu(
id="context-menu-{{ entity.id }}",
ng-if="permissions.write"
)
ul.dropdown-menu
li
a(
@ -134,9 +151,9 @@ script(type='text/ng-template', id='entityListItemTemplate')
.entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController")
.entity-name(
ng-click="select()"
ng-dblclick="startRenaming()"
draggable
droppable
ng-dblclick="permissions.write && startRenaming()"
draggable="permissions.write"
droppable="permissions.write"
accept=".entity-name"
on-drop-callback="onDrop"
)
@ -144,6 +161,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
context-menu
data-target="context-menu-{{ entity.id }}"
context-menu-container="body"
context-menu-disabled="!permissions.write"
)
i.fa.fa-fw.toggle(
ng-if="entity.type == 'folder'"
@ -164,6 +182,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
ng-hide="entity.renaming"
) {{ entity.name }}
input(
ng-if="permissions.write",
ng-show="entity.renaming",
ng-model="inputs.name",
ng-blur="finishRenaming()",
@ -171,7 +190,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
on-enter="finishRenaming()"
)
span.dropdown(ng-show="entity.selected")
span.dropdown(
ng-if="permissions.write"
ng-show="entity.selected"
)
a.dropdown-toggle(href)
i.fa.fa-chevron-down
@ -208,7 +230,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
ng-click="openUploadFileModal()"
) Upload File
.dropdown.context-menu(id="context-menu-{{ entity.id }}")
.dropdown.context-menu(
ng-if="permissions.write"
id="context-menu-{{ entity.id }}"
)
ul.dropdown-menu
li
a(
@ -250,12 +275,13 @@ script(type='text/ng-template', id='entityListItemTemplate')
ul.list-unstyled(
ng-if="entity.type == 'folder'"
ng-show="expanded"
droppable
droppable="permissions.write"
accept=".entity-name"
on-drop-callback="onDrop"
)
file-entity(
entity="child",
permissions="permissions",
ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, 'name']"
)

View file

@ -7,14 +7,35 @@ header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading")
)
i.fa.fa-fw.fa-bars
span.name {{ project.name }}
.toolbar-center.project-name(ng-controller="ProjectNameController")
span.name(
ng-dblclick="startRenaming()",
ng-show="!state.renaming"
) {{ project.name }}
a(href='#', data-toggle="tooltip", title="Rename")
i.fa.fa-pencil
input.form-control(
type="text"
ng-model="inputs.name",
ng-show="state.renaming",
on-enter="finishRenaming()",
ng-blur="finishRenaming()",
select-name-when="state.renaming"
)
a.rename(
href='#',
tooltip-placement="bottom",
tooltip="Rename",
tooltip-append-to-body="true",
ng-click="startRenaming()",
ng-show="!state.renaming"
)
i.fa.fa-pencil
.toolbar-right
a.btn.btn-full-height(
href,
ng-if="permissions.admin",
tooltip="Share",
tooltip-placement="bottom",
ng-click="openShareProjectModal()",

View file

@ -9,7 +9,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
.modal-body.modal-body-share
.container-fluid
.row.public-access-level(ng-show="project.publicAccesLevel == 'private'")
.col-md-12.text-center
.col-xs-12.text-center
| This project is private and can only be accessed by the people below.
|   
a(
@ -17,7 +17,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
ng-click="openMakePublicModal()"
) Make Public
.row.public-access-level(ng-show="project.publicAccesLevel != 'private'")
.col-md-12.text-center
.col-xs-12.text-center
strong(ng-if="project.publicAccesLevel == 'readAndWrite'") This project is public and can be edited by anyone with the URL.
strong(ng-if="project.publicAccesLevel == 'readOnly'") This project is public and can be viewed by anyone with the URL.
|   
@ -26,16 +26,16 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
ng-click="openMakePrivateModal()"
) Make Private
.row.project-member
.col-md-8 {{ project.owner.email }}
.col-xs-8 {{ project.owner.email }}
.text-right(
ng-class="{'col-md-3': project.members.length > 0, 'col-md-4': project.members.length == 0}"
ng-class="{'col-xs-3': project.members.length > 0, 'col-xs-4': project.members.length == 0}"
) Owner
.row.project-member(ng-repeat="member in project.members")
.col-md-8 {{ member.email }}
.col-md-3.text-right
.col-xs-8 {{ member.email }}
.col-xs-3.text-right
span(ng-show="member.privileges == 'readAndWrite'") Can Edit
span(ng-show="member.privileges == 'readOnly'") Read Only
.col-md-1
.col-xs-1
a(
href
tooltip="Remove collaborator"

View file

@ -1,4 +1,17 @@
div#trackChanges(ng-show="ui.view == 'track-changes'")
.upgrade-prompt(ng-show="!project.features.versioning")
.message(ng-show="project.owner._id == user.id")
p You need to upgrade your account to use the History feature.
p
a.btn.btn-info(
href="/user/subscription/plans"
target="_blank"
ng-click="startedFreeTrial = true"
) Start Free Trial
p.small(ng-show="startedFreeTrial") Please refresh the page after starting your free trial.
.message(ng-show="project.owner._id != user.id")
p Please ask the project owner to upgrade to use the History feature.
aside.change-list(
ng-controller="TrackChangesListController"
infinite-scroll="loadMore()"
@ -57,8 +70,11 @@ div#trackChanges(ng-show="ui.view == 'track-changes'")
div.users
div.user(ng-repeat="update_user in update.meta.users")
.color-square(ng-style="{'background-color': 'hsl({{ update_user.hue }}, 100%, 50%)'}")
span(ng-if="update_user.id != user.id") {{user.first_name}} {{user.last_name}}
span(ng-if="update_user.id != user.id") {{update_user.first_name}} {{update_user.last_name}}
span(ng-if="update_user.id == user.id") You
div.user(ng-if="update.meta.users.length == 0")
.color-square(style="background-color: hsl(100, 100%, 50%)")
span Anonymous
.loading(ng-show="trackChanges.loading")
i.fa.fa-spin.fa-refresh

View file

@ -5,7 +5,9 @@ define [
"ide/editor/EditorManager"
"ide/online-users/OnlineUsersManager"
"ide/track-changes/TrackChangesManager"
"ide/permissions/PermissionsManager"
"ide/pdf/PdfManager"
"ide/binary-files/BinaryFilesManager"
"ide/settings/index"
"ide/share/index"
"ide/chat/index"
@ -22,7 +24,9 @@ define [
EditorManager
OnlineUsersManager
TrackChangesManager
PermissionsManager
PdfManager
BinaryFilesManager
) ->
App.controller "IdeController", ["$scope", "$timeout", "ide", ($scope, $timeout, ide) ->
# Don't freak out if we're already in an apply callback
@ -59,6 +63,8 @@ define [
ide.onlineUsersManager = new OnlineUsersManager(ide, $scope)
ide.trackChangesManager = new TrackChangesManager(ide, $scope)
ide.pdfManager = new PdfManager(ide, $scope)
ide.permissionsManager = new PermissionsManager(ide, $scope)
ide.binaryFilesManager = new BinaryFilesManager(ide, $scope)
]
angular.bootstrap(document.body, ["SharelatexApp"])

View file

@ -0,0 +1,12 @@
define [
"ide/binary-files/controllers/BinaryFileController"
], () ->
class BinaryFilesManager
constructor: (@ide, @$scope) ->
@$scope.$on "entity:selected", (event, entity) =>
if (@$scope.ui.view != "track-changes" and entity.type == "file")
@openFile(entity)
openFile: (file) ->
@$scope.ui.view = "file"
@$scope.openFile = file

View file

@ -0,0 +1,7 @@
define [
"base"
], (App) ->
App.controller "BinaryFileController", ["$scope", ($scope) ->
$scope.extension = (file) ->
return file.name.split(".").pop()?.toLowerCase()
]

View file

@ -57,6 +57,7 @@ define [], () ->
@$scope.$apply () =>
@$scope.protocolVersion = protocolVersion
@$scope.project = project
@$scope.permissionsLevel = permissionsLevel
@$scope.state.load_progress = 100
@$scope.state.loading = false
@$scope.$emit "project:joined"
@ -79,6 +80,7 @@ define [], () ->
countdown = 3 + Math.floor(Math.random() * 7)
@$scope.$apply () =>
@$scope.connection.reconnecting = false
@$scope.connection.reconnection_countdown = countdown
setTimeout(=>

View file

@ -149,6 +149,10 @@ define [
@ide.connectionManager.disconnect()
return
if Math.random() < (@ide.ignoreRate or 0)
console.log "Simulating lost update"
return
if update?.doc == @doc_id and @doc?
@doc.processUpdateFromServer update

View file

@ -1,6 +1,7 @@
define [
"ide/editor/Document"
"ide/editor/directives/aceEditor"
"ide/editor/controllers/SavingNotificationController"
], (Document) ->
class EditorManager
constructor: (@ide, @$scope) ->
@ -14,7 +15,7 @@ define [
}
@$scope.$on "entity:selected", (event, entity) =>
if (@$scope.ui.view == "editor" and entity.type == "doc")
if (@$scope.ui.view != "track-changes" and entity.type == "doc")
@openDoc(entity)
initialized = false
@ -77,25 +78,17 @@ define [
_bindToDocumentEvents: (doc, sharejs_doc) ->
sharejs_doc.on "error", (error) =>
console.error "DOC ERROR", error
@openDoc(doc, forceReopen: true)
#TODO!!!
# Modal.createModal
# title: "Out of sync"
# message: "Sorry, this file has gone out of sync and we need to do a full refresh. Please let us know if this happens frequently."
# buttons:[
# text: "Ok"
# ]
@ide.showGenericMessageModal(
"Out of sync"
"Sorry, this file has gone out of sync and we need to do a full refresh. Please let us know if this happens frequently."
)
sharejs_doc.on "externalUpdate", () =>
#TODO!!!
# Modal.createModal
# title: "Document Updated Externally"
# message: "This document was just updated externally. Any recent changes you have made may have been overwritten. To see previous versions please look in the history."
# buttons:[
# text: "Ok"
# ]
@ide.showGenericMessageModal(
"Document Updated Externally"
"This document was just updated externally. Any recent changes you have made may have been overwritten. To see previous versions please look in the history."
)
_unbindFromDocumentEvents: (document) ->
document.off()

View file

@ -0,0 +1,33 @@
define [
"base"
"ide/editor/Document"
], (App, Document) ->
App.controller "SavingNotificationController", ["$scope", "$interval", "ide", ($scope, $interval, ide) ->
$interval () ->
pollSavedStatus()
, 1000
$(window).bind 'beforeunload', () =>
warnAboutUnsavedChanges()
$scope.docSavingStatus = {}
pollSavedStatus = () ->
oldStatus = $scope.docSavingStatus
$scope.docSavingStatus = {}
for doc_id, doc of Document.openDocs
saving = doc.pollSavedStatus()
if !saving
if oldStatus[doc_id]?
$scope.docSavingStatus[doc_id] = oldStatus[doc_id]
$scope.docSavingStatus[doc_id].unsavedSeconds += 1
else
$scope.docSavingStatus[doc_id] = {
unsavedSeconds: 0
doc: ide.fileTreeManager.findEntityById(doc_id)
}
warnAboutUnsavedChanges = () ->
if Document.hasUnsavedChanges()
return "You have unsaved changes. If you leave now they will not be saved."
]

View file

@ -204,16 +204,16 @@ define [
_getColorScheme: (hue) ->
if @_isDarkTheme()
return {
cursor: "hsl(#{hue}, 100%, 50%)"
labelBackgroundColor: "hsl(#{hue}, 100%, 50%)"
cursor: "hsl(#{hue}, 70%, 50%)"
labelBackgroundColor: "hsl(#{hue}, 70%, 50%)"
highlightBackgroundColor: "hsl(#{hue}, 100%, 28%);"
strikeThroughBackgroundColor: "hsl(#{hue}, 100%, 20%);"
strikeThroughForegroundColor: "hsl(#{hue}, 100%, 60%);"
}
else
return {
cursor: "hsl(#{hue}, 100%, 50%)"
labelBackgroundColor: "hsl(#{hue}, 100%, 50%)"
cursor: "hsl(#{hue}, 70%, 50%)"
labelBackgroundColor: "hsl(#{hue}, 70%, 50%)"
highlightBackgroundColor: "hsl(#{hue}, 70%, 85%);"
strikeThroughBackgroundColor: "hsl(#{hue}, 70%, 95%);"
strikeThroughForegroundColor: "hsl(#{hue}, 70%, 40%);"

View file

@ -5,6 +5,7 @@ define [
"ide/file-tree/controllers/FileTreeController"
"ide/file-tree/controllers/FileTreeEntityController"
"ide/file-tree/controllers/FileTreeFolderController"
"ide/file-tree/controllers/FileTreeRootFolderController"
], () ->
class FileTreeManager
constructor: (@ide, @$scope) ->
@ -59,6 +60,7 @@ define [
@ide.socket.on "reciveEntityMove", (entity_id, folder_id) =>
entity = @findEntityById(entity_id)
folder = @findEntityById(folder_id)
console.log "Got recive ENTITY", entity_id, folder_id, entity, folder
@$scope.$apply () =>
@_moveEntityInScope(entity, folder)
@ -68,7 +70,15 @@ define [
entity.selected = false
entity.selected = true
findSelectedEntity: () ->
selected = null
@forEachEntity (entity) ->
selected = entity if entity.selected
return selected
findEntityById: (id, options = {}) ->
return @$scope.rootFolder if @$scope.rootFolder.id == id
entity = @_findEntityByIdInFolder @$scope.rootFolder, id
return entity if entity?
@ -250,7 +260,7 @@ define [
_csrf: window.csrfToken
}
_deleteEntityFromScope: (entity) ->
_deleteEntityFromScope: (entity, options = { moveToDeleted: true }) ->
parent_folder = null
@forEachEntity (possible_entity, folder) ->
if possible_entity == entity
@ -261,11 +271,11 @@ define [
if index > -1
parent_folder.children.splice(index, 1)
if entity.type == "doc"
if entity.type == "doc" and options.moveToDeleted
entity.deleted = true
@$scope.deletedDocs.push entity
_moveEntityInScope: (entity, parent_folder) ->
return if entity in parent_folder.children
@_deleteEntityFromScope(entity)
@_deleteEntityFromScope(entity, moveToDeleted: false)
parent_folder.children.push(entity)

View file

@ -0,0 +1,13 @@
define [
"base"
], (App) ->
App.controller "FileTreeRootFolderController", ["$scope", "ide", ($scope, ide) ->
console.log "CREATING FileTreeRootFolderController"
rootFolder = $scope.rootFolder
console.log "ROOT FOLDER", rootFolder
$scope.onDrop = (events, ui) ->
source = $(ui.draggable).scope().entity
console.log "DROPPED INTO ROOT", source, rootFolder
return if !source?
ide.fileTreeManager.moveEntity(source, rootFolder)
]

View file

@ -4,9 +4,11 @@ define [
App.directive "draggable", () ->
return {
link: (scope, element, attrs) ->
element.draggable
delay: 250
opacity: 0.7
helper: "clone"
scroll: true
scope.$watch attrs.draggable, (draggable) ->
if draggable
element.draggable
delay: 250
opacity: 0.7
helper: "clone"
scroll: true
}

View file

@ -7,9 +7,11 @@ define [
onDropCallback: "="
}
link: (scope, element, attrs) ->
element.droppable
greedy: true
hoverClass: "droppable-hover"
accept: attrs.accept
drop: scope.onDropCallback
scope.$watch attrs.droppable, (droppable) ->
if droppable
element.droppable
greedy: true
hoverClass: "droppable-hover"
accept: attrs.accept
drop: scope.onDropCallback
}

View file

@ -6,10 +6,18 @@ define [
restrict: "E"
scope: {
entity: "="
permissions: "="
}
templateUrl: "entityListItemTemplate"
compile: (element) ->
RecursionHelper.compile element, (scope, element, attrs, ctrl) ->
# Link function here if needed
# Don't freak out if we're already in an apply callback
scope.$originalApply = scope.$apply
scope.$apply = (fn = () ->) ->
phase = @$root.$$phase
if (phase == '$apply' || phase == '$digest')
fn()
else
@$originalApply(fn);
}
]

View file

@ -56,7 +56,7 @@ define [
OWN_HUE: 200 # We will always appear as this color to ourselves
ANONYMOUS_HUE: 100
getHueForUserId: (user_id) ->
if !user_id?
if !user_id? or user_id == "anonymous-user"
return @ANONYMOUS_HUE
if window.user.id == user_id

View file

@ -0,0 +1,19 @@
define [], () ->
class PermissionsManager
constructor: (@ide, @$scope) ->
@$scope.$watch "permissionsLevel", (permissionsLevel) =>
@$scope.permissions =
read: false
write: false
admin: false
if permissionsLevel?
if permissionsLevel == "readOnly"
@$scope.permissions.read = true
else if permissionsLevel == "readAndWrite"
@$scope.permissions.read = true
@$scope.permissions.write = true
else if permissionsLevel == "owner"
@$scope.permissions.read = true
@$scope.permissions.write = true
@$scope.permissions.admin = true

View file

@ -3,7 +3,7 @@ define [
], (App) ->
# We create and provide this as service so that we can access the global ide
# from within other parts of the angular app.
App.factory "ide", ["$http", ($http) ->
App.factory "ide", ["$http", "$modal", ($http, $modal) ->
ide = {}
ide.$http = $http
@ -16,5 +16,22 @@ define [
ide.showGenericServerErrorMessage = () ->
console.error "GENERIC SERVER ERROR MESSAGE STUB"
ide.showGenericMessageModal = (title, message) ->
$modal.open {
templateUrl: "genericMessageModalTemplate"
controller: "GenericMessageModalController"
resolve:
title: -> title
message: -> message
}
return ide
]
App.controller "GenericMessageModalController", ["$scope", "$modalInstance", "title", "message", ($scope, $modalInstance, title, message) ->
$scope.title = title
$scope.message = message
$scope.done = () ->
$modalInstance.close()
]

View file

@ -0,0 +1,26 @@
define [
"base"
], (App) ->
App.controller "ProjectNameController", ["$scope", "settings", "ide", ($scope, settings, ide) ->
$scope.state =
renaming: false
$scope.inputs = {}
$scope.startRenaming = () ->
$scope.inputs.name = $scope.project.name
$scope.state.renaming = true
$scope.$emit "project:rename:start"
$scope.finishRenaming = () ->
$scope.project.name = $scope.inputs.name
settings.saveProjectSettings({name: $scope.inputs.name})
$scope.state.renaming = false
ide.socket.on "projectNameUpdated", (name) ->
$scope.$apply () ->
$scope.project.name = name
$scope.$watch "project.name", (name) ->
if name?
window.document.title = name + " - Online LaTeX Editor ShareLaTeX"
]

View file

@ -1,5 +1,7 @@
define [
"ide/settings/services/settings"
"ide/settings/controllers/SettingsController"
"ide/settings/controllers/ProjectNameController"
], () ->

View file

@ -9,10 +9,9 @@ define [
@$scope.toggleTrackChanges = () =>
if @$scope.ui.view == "track-changes"
@$scope.ui.view = "editor"
@hide()
else
@$scope.ui.view = "track-changes"
@onShow()
@show()
@$scope.$watch "trackChanges.selection.updates", (updates) =>
if updates? and updates.length > 0
@ -24,11 +23,14 @@ define [
@$scope.trackChanges.selection.doc = entity
@reloadDiff()
onShow: () ->
show: () ->
@$scope.ui.view = "track-changes"
@reset()
# @fetchNextBatchOfChanges()
# .success () =>
# @autoSelectRecentUpdates()
hide: () ->
@$scope.ui.view = "editor"
# Make sure we run the 'open' logic for whatever is currently selected
@$scope.$emit "entity:selected", @ide.fileTreeManager.findSelectedEntity()
reset: () ->
@$scope.trackChanges = {
@ -157,21 +159,24 @@ define [
}
if entry.i? or entry.d?
name = "#{entry.meta.user.first_name} #{entry.meta.user.last_name}"
if entry.meta.user.id == @$scope.user.id
if entry.meta.user?
name = "#{entry.meta.user.first_name} #{entry.meta.user.last_name}"
else
name = "Anonymous"
if entry.meta.user?.id == @$scope.user.id
name = "you"
date = moment(entry.meta.end_ts).format("Do MMM YYYY, h:mm a")
if entry.i?
highlights.push {
label: "Added by #{name} on #{date}"
highlight: range
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user.id)
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user?.id)
}
else if entry.d?
highlights.push {
label: "Deleted by #{name} on #{date}"
strikeThrough: range
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user.id)
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user?.id)
}
return {text, highlights}

View file

@ -5,6 +5,7 @@
@import "./editor/pdf.less";
@import "./editor/share.less";
@import "./editor/chat.less";
@import "./editor/binary-file.less";
.full-size {
position: absolute;
@ -17,10 +18,15 @@
.global-alerts {
position: absolute;
z-index: 20;
top: (@line-height-computed / 4);
top: 2px;
width: 400px;
left: 50%;
margin-left: -200px;
.alert {
padding: (@line-height-computed / 4);
font-size: 14px;
margin-bottom: (@line-height-computed / 4);
}
}
#chat-wrapper {
@ -57,6 +63,35 @@
}
}
.project-name {
.name {
display: inline-block;
max-width: 250px;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
padding: 6px;
color: @gray;
font-weight: 700;
white-space: nowrap;
}
input {
height: 30px;
margin-top: 4px;
text-align: center;
padding: 6px;
font-weight: 700;
}
a.rename {
visibility: hidden;
}
&:hover {
a.rename {
visibility: visible;
}
}
}
// The internal components of the aceEditor directive
.ace-editor-wrapper {
.full-size;

View file

@ -0,0 +1,20 @@
.binary-file {
padding: @line-height-computed / 2;
background-color: @gray-lightest;
text-align: center;
img {
max-width: 100%;
max-height: 90%;
display: block;
margin: auto;
margin-bottom: @line-height-computed / 2;
border: 1px solid @gray;
.box-shadow(0 2px 3px @gray;);
background-color: white;
}
p.no-preview {
font-size: 24px;
color: @gray;
}
}

View file

@ -9,6 +9,10 @@ aside#file-tree {
left: 0;
right: 0;
overflow-y: auto;
&.no-toolbar {
top: 0;
}
}
h3 {

View file

@ -73,18 +73,26 @@
}
}
.log-btn {
position: relative;
.label {
position: absolute;
top: 0;
right: 0;
padding: .15em .6em .2em;
font-size: 60%;
}
&.active, &:active {
.toolbar {
.log-btn {
position: relative;
.label {
display: none;
position: absolute;
top: 0;
right: 0;
padding: .15em .6em .2em;
font-size: 60%;
}
&.active, &:active {
.label {
display: none;
}
color: white;
background-color: @link-color;
.box-shadow(inset 0 3px 5px rgba(0, 0, 0, 0.225));
&:hover {
color: white;
}
}
}
}

View file

@ -13,11 +13,6 @@
color: @gray-dark;
text-decoration: none;
}
&.active, &:active {
color: white;
background-color: @link-color;
.box-shadow(inset 0 3px 5px rgba(0, 0, 0, 0.225));
}
}
.btn-full-height {
@ -47,6 +42,17 @@
}
}
.toolbar-center {
width: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
text-align: center;
text-overflow: ellipsis;
overflow: hidden;
}
&.toolbar-header {
box-shadow: 0 0 2px #ccc;
position: absolute;

View file

@ -9,117 +9,25 @@
@range-bar-selected-offset: 14px;
#trackChanges {
// .track-changes-diff {
// position: absolute;
// right: @changesListWidth + 1px;
// left: 0;
// top: 0;
// bottom: 0;
// height: 100%;
// .ace_editor {
// position: absolute;
// top: 42px;
// left: 0;
// right: 0;
// bottom: 0;
// .ace_active-line, .ace_cursor-layer, .ace_gutter-active-line {
// display: none;
// }
// }
// .track-changes-diff-toolbar {
// position: absolute;
// top: 0;
// left: 0;
// right: -1px;
// height: 32px;
// padding: 5px 5px 5px 5px;
// margin: 0;
// background-color: #282828;
// color: white;
// border-right: 1px solid white;
// .number-of-changes, .restore {
// position: absolute;
// }
// .number-of-changes {
// left: 10px;
// bottom: 7px;
// }
// .restore {
// right: 10px;
// bottom: 5px;
// padding: 3px 9px;
// }
// }
// }
// .track-changes-upgrade-control, .track-changes-upgrade-popup {
// position: absolute;
// top: 0;
// bottom: 0;
// left: 0;
// right: 0;
// z-index: 100;
// }
// .track-changes-upgrade-popup {
// background-color: rgba(128,128,128,0.4);
// .message {
// margin: auto;
// margin-top: 200px;
// padding: 10px 10px 14px 10px;
// width: 400px;
// font-weight: bold;
// text-align: center;
// background-color: white;
// .border-radius(8px);
// }
// }
// .track-changes-upgrade-control {
// background-color: #eeeeee;
// text-align: center;
// .message {
// font-size: 18px;
// margin: 12px;
// margin-top: 36px;
// }
// }
// .deleted-background,
// .deleted-foreground,
// .inserted-background,
// .name-marker,
// .changes-before,
// .changes-after {
// position: absolute;
// z-index: 2;
// }
// .name-marker {
// font-size: 0.8em;
// padding: 2px 6px;
// .border-radius(3px 3px 3px 3px);
// position: absolute;
// border: 1px solid #999;
// left: 0;
// white-space: pre;
// }
// .changes-before {
// top: 6px;
// right: 6px;
// }
// .changes-after {
// bottom: 6px;
// right: 6px;
// }
// .changes-before, .changes-after {
// padding: 4px 8px;
// background-color: #eee;
// border: 1px solid #999;
// .border-radius(3px);
// }
.upgrade-prompt {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
background-color: rgba(128,128,128,0.4);
.message {
margin: auto;
margin-top: 100px;
padding: 10px 10px 14px 10px;
width: 500px;
font-weight: bold;
text-align: center;
background-color: white;
border-radius: 8px;
}
}
.diff {
margin-right: @changesListWidth;