mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge branch 'master-redesign' into master-redesign-templates-and-blog
This commit is contained in:
commit
86a9d08e5c
32 changed files with 446 additions and 201 deletions
|
@ -33,6 +33,14 @@ block content
|
||||||
.alert.alert-warning.small(ng-if="connection.reconnecting")
|
.alert.alert-warning.small(ng-if="connection.reconnecting")
|
||||||
strong 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
|
include ./editor/left-menu
|
||||||
|
|
||||||
#chat-wrapper(
|
#chat-wrapper(
|
||||||
|
@ -56,11 +64,23 @@ block content
|
||||||
|
|
||||||
.ui-layout-center
|
.ui-layout-center
|
||||||
include ./editor/editor
|
include ./editor/editor
|
||||||
|
include ./editor/binary-file
|
||||||
include ./editor/track-changes
|
include ./editor/track-changes
|
||||||
|
|
||||||
.ui-layout-east
|
.ui-layout-east
|
||||||
include ./editor/chat
|
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')
|
script(src='/socket.io/socket.io.js')
|
||||||
|
|
||||||
|
|
19
services/web/app/views/project/editor/binary-file.jade
Normal file
19
services/web/app/views/project/editor/binary-file.jade
Normal 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 }}
|
|
@ -25,7 +25,8 @@ div.full-size(
|
||||||
cursor-position="editor.cursorPosition",
|
cursor-position="editor.cursorPosition",
|
||||||
goto-line="editor.gotoLine",
|
goto-line="editor.gotoLine",
|
||||||
resize-on="layout:main:resize,layout:pdf:resize",
|
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
|
.ui-layout-east
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
aside#file-tree(ng-controller="FileTreeController")
|
aside#file-tree(ng-controller="FileTreeController")
|
||||||
.toolbar.toolbar-small
|
.toolbar.toolbar-small(ng-if="permissions.write")
|
||||||
a(
|
a(
|
||||||
href,
|
href,
|
||||||
ng-click="openNewDocModal()",
|
ng-click="openNewDocModal()",
|
||||||
|
@ -39,10 +39,19 @@ aside#file-tree(ng-controller="FileTreeController")
|
||||||
)
|
)
|
||||||
i.fa.fa-trash-o
|
i.fa.fa-trash-o
|
||||||
|
|
||||||
.file-tree-inner
|
.file-tree-inner(
|
||||||
ul.list-unstyled.file-tree-list
|
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(
|
file-entity(
|
||||||
entity="entity",
|
entity="entity",
|
||||||
|
permissions="permissions",
|
||||||
ng-repeat="entity in rootFolder.children | orderBy:[orderByFoldersFirst, 'name']"
|
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(ng-if="entity.type != 'folder'")
|
||||||
.entity-name(
|
.entity-name(
|
||||||
ng-click="select()"
|
ng-click="select()"
|
||||||
ng-dblclick="startRenaming()"
|
ng-dblclick="permissions.write && startRenaming()"
|
||||||
draggable
|
draggable="permissions.write"
|
||||||
context-menu
|
context-menu
|
||||||
data-target="context-menu-{{ entity.id }}"
|
data-target="context-menu-{{ entity.id }}"
|
||||||
context-menu-container="body"
|
context-menu-container="body"
|
||||||
|
context-menu-disabled="!permissions.write"
|
||||||
)
|
)
|
||||||
//- Just a spacer to align with folders
|
//- Just a spacer to align with folders
|
||||||
i.fa.fa-fw.toggle(ng-if="entity.type != 'folder'")
|
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"
|
ng-hide="entity.renaming"
|
||||||
) {{ entity.name }}
|
) {{ entity.name }}
|
||||||
input(
|
input(
|
||||||
|
ng-if="permissions.write",
|
||||||
ng-show="entity.renaming",
|
ng-show="entity.renaming",
|
||||||
ng-model="inputs.name",
|
ng-model="inputs.name",
|
||||||
ng-blur="finishRenaming()",
|
ng-blur="finishRenaming()",
|
||||||
|
@ -95,7 +106,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||||
on-enter="finishRenaming()"
|
on-enter="finishRenaming()"
|
||||||
)
|
)
|
||||||
|
|
||||||
span.dropdown(ng-show="entity.selected")
|
span.dropdown(
|
||||||
|
ng-show="entity.selected",
|
||||||
|
ng-if="permissions.write"
|
||||||
|
)
|
||||||
a.dropdown-toggle(href)
|
a.dropdown-toggle(href)
|
||||||
i.fa.fa-chevron-down
|
i.fa.fa-chevron-down
|
||||||
|
|
||||||
|
@ -113,7 +127,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||||
ng-click="openDeleteModal()"
|
ng-click="openDeleteModal()"
|
||||||
) Delete
|
) 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
|
ul.dropdown-menu
|
||||||
li
|
li
|
||||||
a(
|
a(
|
||||||
|
@ -134,9 +151,9 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||||
.entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController")
|
.entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController")
|
||||||
.entity-name(
|
.entity-name(
|
||||||
ng-click="select()"
|
ng-click="select()"
|
||||||
ng-dblclick="startRenaming()"
|
ng-dblclick="permissions.write && startRenaming()"
|
||||||
draggable
|
draggable="permissions.write"
|
||||||
droppable
|
droppable="permissions.write"
|
||||||
accept=".entity-name"
|
accept=".entity-name"
|
||||||
on-drop-callback="onDrop"
|
on-drop-callback="onDrop"
|
||||||
)
|
)
|
||||||
|
@ -144,6 +161,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||||
context-menu
|
context-menu
|
||||||
data-target="context-menu-{{ entity.id }}"
|
data-target="context-menu-{{ entity.id }}"
|
||||||
context-menu-container="body"
|
context-menu-container="body"
|
||||||
|
context-menu-disabled="!permissions.write"
|
||||||
)
|
)
|
||||||
i.fa.fa-fw.toggle(
|
i.fa.fa-fw.toggle(
|
||||||
ng-if="entity.type == 'folder'"
|
ng-if="entity.type == 'folder'"
|
||||||
|
@ -164,6 +182,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||||
ng-hide="entity.renaming"
|
ng-hide="entity.renaming"
|
||||||
) {{ entity.name }}
|
) {{ entity.name }}
|
||||||
input(
|
input(
|
||||||
|
ng-if="permissions.write",
|
||||||
ng-show="entity.renaming",
|
ng-show="entity.renaming",
|
||||||
ng-model="inputs.name",
|
ng-model="inputs.name",
|
||||||
ng-blur="finishRenaming()",
|
ng-blur="finishRenaming()",
|
||||||
|
@ -171,7 +190,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||||
on-enter="finishRenaming()"
|
on-enter="finishRenaming()"
|
||||||
)
|
)
|
||||||
|
|
||||||
span.dropdown(ng-show="entity.selected")
|
span.dropdown(
|
||||||
|
ng-if="permissions.write"
|
||||||
|
ng-show="entity.selected"
|
||||||
|
)
|
||||||
a.dropdown-toggle(href)
|
a.dropdown-toggle(href)
|
||||||
i.fa.fa-chevron-down
|
i.fa.fa-chevron-down
|
||||||
|
|
||||||
|
@ -208,7 +230,10 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||||
ng-click="openUploadFileModal()"
|
ng-click="openUploadFileModal()"
|
||||||
) Upload File
|
) 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
|
ul.dropdown-menu
|
||||||
li
|
li
|
||||||
a(
|
a(
|
||||||
|
@ -250,12 +275,13 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
||||||
ul.list-unstyled(
|
ul.list-unstyled(
|
||||||
ng-if="entity.type == 'folder'"
|
ng-if="entity.type == 'folder'"
|
||||||
ng-show="expanded"
|
ng-show="expanded"
|
||||||
droppable
|
droppable="permissions.write"
|
||||||
accept=".entity-name"
|
accept=".entity-name"
|
||||||
on-drop-callback="onDrop"
|
on-drop-callback="onDrop"
|
||||||
)
|
)
|
||||||
file-entity(
|
file-entity(
|
||||||
entity="child",
|
entity="child",
|
||||||
|
permissions="permissions",
|
||||||
ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, 'name']"
|
ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, 'name']"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,35 @@ header.toolbar.toolbar-header(ng-cloak, ng-hide="state.loading")
|
||||||
)
|
)
|
||||||
i.fa.fa-fw.fa-bars
|
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")
|
input.form-control(
|
||||||
i.fa.fa-pencil
|
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
|
.toolbar-right
|
||||||
a.btn.btn-full-height(
|
a.btn.btn-full-height(
|
||||||
href,
|
href,
|
||||||
|
ng-if="permissions.admin",
|
||||||
tooltip="Share",
|
tooltip="Share",
|
||||||
tooltip-placement="bottom",
|
tooltip-placement="bottom",
|
||||||
ng-click="openShareProjectModal()",
|
ng-click="openShareProjectModal()",
|
||||||
|
|
|
@ -9,7 +9,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
|
||||||
.modal-body.modal-body-share
|
.modal-body.modal-body-share
|
||||||
.container-fluid
|
.container-fluid
|
||||||
.row.public-access-level(ng-show="project.publicAccesLevel == 'private'")
|
.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.
|
| This project is private and can only be accessed by the people below.
|
||||||
|
|
|
|
||||||
a(
|
a(
|
||||||
|
@ -17,7 +17,7 @@ script(type='text/ng-template', id='shareProjectModalTemplate')
|
||||||
ng-click="openMakePublicModal()"
|
ng-click="openMakePublicModal()"
|
||||||
) Make Public
|
) Make Public
|
||||||
.row.public-access-level(ng-show="project.publicAccesLevel != 'private'")
|
.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 == '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.
|
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()"
|
ng-click="openMakePrivateModal()"
|
||||||
) Make Private
|
) Make Private
|
||||||
.row.project-member
|
.row.project-member
|
||||||
.col-md-8 {{ project.owner.email }}
|
.col-xs-8 {{ project.owner.email }}
|
||||||
.text-right(
|
.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
|
) Owner
|
||||||
.row.project-member(ng-repeat="member in project.members")
|
.row.project-member(ng-repeat="member in project.members")
|
||||||
.col-md-8 {{ member.email }}
|
.col-xs-8 {{ member.email }}
|
||||||
.col-md-3.text-right
|
.col-xs-3.text-right
|
||||||
span(ng-show="member.privileges == 'readAndWrite'") Can Edit
|
span(ng-show="member.privileges == 'readAndWrite'") Can Edit
|
||||||
span(ng-show="member.privileges == 'readOnly'") Read Only
|
span(ng-show="member.privileges == 'readOnly'") Read Only
|
||||||
.col-md-1
|
.col-xs-1
|
||||||
a(
|
a(
|
||||||
href
|
href
|
||||||
tooltip="Remove collaborator"
|
tooltip="Remove collaborator"
|
||||||
|
|
|
@ -1,4 +1,17 @@
|
||||||
div#trackChanges(ng-show="ui.view == 'track-changes'")
|
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(
|
aside.change-list(
|
||||||
ng-controller="TrackChangesListController"
|
ng-controller="TrackChangesListController"
|
||||||
infinite-scroll="loadMore()"
|
infinite-scroll="loadMore()"
|
||||||
|
@ -57,8 +70,11 @@ div#trackChanges(ng-show="ui.view == 'track-changes'")
|
||||||
div.users
|
div.users
|
||||||
div.user(ng-repeat="update_user in update.meta.users")
|
div.user(ng-repeat="update_user in update.meta.users")
|
||||||
.color-square(ng-style="{'background-color': 'hsl({{ update_user.hue }}, 100%, 50%)'}")
|
.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
|
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")
|
.loading(ng-show="trackChanges.loading")
|
||||||
i.fa.fa-spin.fa-refresh
|
i.fa.fa-spin.fa-refresh
|
||||||
|
|
|
@ -5,7 +5,9 @@ define [
|
||||||
"ide/editor/EditorManager"
|
"ide/editor/EditorManager"
|
||||||
"ide/online-users/OnlineUsersManager"
|
"ide/online-users/OnlineUsersManager"
|
||||||
"ide/track-changes/TrackChangesManager"
|
"ide/track-changes/TrackChangesManager"
|
||||||
|
"ide/permissions/PermissionsManager"
|
||||||
"ide/pdf/PdfManager"
|
"ide/pdf/PdfManager"
|
||||||
|
"ide/binary-files/BinaryFilesManager"
|
||||||
"ide/settings/index"
|
"ide/settings/index"
|
||||||
"ide/share/index"
|
"ide/share/index"
|
||||||
"ide/chat/index"
|
"ide/chat/index"
|
||||||
|
@ -22,7 +24,9 @@ define [
|
||||||
EditorManager
|
EditorManager
|
||||||
OnlineUsersManager
|
OnlineUsersManager
|
||||||
TrackChangesManager
|
TrackChangesManager
|
||||||
|
PermissionsManager
|
||||||
PdfManager
|
PdfManager
|
||||||
|
BinaryFilesManager
|
||||||
) ->
|
) ->
|
||||||
App.controller "IdeController", ["$scope", "$timeout", "ide", ($scope, $timeout, ide) ->
|
App.controller "IdeController", ["$scope", "$timeout", "ide", ($scope, $timeout, ide) ->
|
||||||
# Don't freak out if we're already in an apply callback
|
# Don't freak out if we're already in an apply callback
|
||||||
|
@ -59,6 +63,8 @@ define [
|
||||||
ide.onlineUsersManager = new OnlineUsersManager(ide, $scope)
|
ide.onlineUsersManager = new OnlineUsersManager(ide, $scope)
|
||||||
ide.trackChangesManager = new TrackChangesManager(ide, $scope)
|
ide.trackChangesManager = new TrackChangesManager(ide, $scope)
|
||||||
ide.pdfManager = new PdfManager(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"])
|
angular.bootstrap(document.body, ["SharelatexApp"])
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
||||||
|
define [
|
||||||
|
"base"
|
||||||
|
], (App) ->
|
||||||
|
App.controller "BinaryFileController", ["$scope", ($scope) ->
|
||||||
|
$scope.extension = (file) ->
|
||||||
|
return file.name.split(".").pop()?.toLowerCase()
|
||||||
|
]
|
|
@ -57,6 +57,7 @@ define [], () ->
|
||||||
@$scope.$apply () =>
|
@$scope.$apply () =>
|
||||||
@$scope.protocolVersion = protocolVersion
|
@$scope.protocolVersion = protocolVersion
|
||||||
@$scope.project = project
|
@$scope.project = project
|
||||||
|
@$scope.permissionsLevel = permissionsLevel
|
||||||
@$scope.state.load_progress = 100
|
@$scope.state.load_progress = 100
|
||||||
@$scope.state.loading = false
|
@$scope.state.loading = false
|
||||||
@$scope.$emit "project:joined"
|
@$scope.$emit "project:joined"
|
||||||
|
@ -79,6 +80,7 @@ define [], () ->
|
||||||
countdown = 3 + Math.floor(Math.random() * 7)
|
countdown = 3 + Math.floor(Math.random() * 7)
|
||||||
|
|
||||||
@$scope.$apply () =>
|
@$scope.$apply () =>
|
||||||
|
@$scope.connection.reconnecting = false
|
||||||
@$scope.connection.reconnection_countdown = countdown
|
@$scope.connection.reconnection_countdown = countdown
|
||||||
|
|
||||||
setTimeout(=>
|
setTimeout(=>
|
||||||
|
|
|
@ -149,6 +149,10 @@ define [
|
||||||
@ide.connectionManager.disconnect()
|
@ide.connectionManager.disconnect()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if Math.random() < (@ide.ignoreRate or 0)
|
||||||
|
console.log "Simulating lost update"
|
||||||
|
return
|
||||||
|
|
||||||
if update?.doc == @doc_id and @doc?
|
if update?.doc == @doc_id and @doc?
|
||||||
@doc.processUpdateFromServer update
|
@doc.processUpdateFromServer update
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
define [
|
define [
|
||||||
"ide/editor/Document"
|
"ide/editor/Document"
|
||||||
"ide/editor/directives/aceEditor"
|
"ide/editor/directives/aceEditor"
|
||||||
|
"ide/editor/controllers/SavingNotificationController"
|
||||||
], (Document) ->
|
], (Document) ->
|
||||||
class EditorManager
|
class EditorManager
|
||||||
constructor: (@ide, @$scope) ->
|
constructor: (@ide, @$scope) ->
|
||||||
|
@ -14,7 +15,7 @@ define [
|
||||||
}
|
}
|
||||||
|
|
||||||
@$scope.$on "entity:selected", (event, entity) =>
|
@$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)
|
@openDoc(entity)
|
||||||
|
|
||||||
initialized = false
|
initialized = false
|
||||||
|
@ -77,25 +78,17 @@ define [
|
||||||
|
|
||||||
_bindToDocumentEvents: (doc, sharejs_doc) ->
|
_bindToDocumentEvents: (doc, sharejs_doc) ->
|
||||||
sharejs_doc.on "error", (error) =>
|
sharejs_doc.on "error", (error) =>
|
||||||
console.error "DOC ERROR", error
|
|
||||||
@openDoc(doc, forceReopen: true)
|
@openDoc(doc, forceReopen: true)
|
||||||
|
@ide.showGenericMessageModal(
|
||||||
#TODO!!!
|
"Out of sync"
|
||||||
# Modal.createModal
|
"Sorry, this file has gone out of sync and we need to do a full refresh. Please let us know if this happens frequently."
|
||||||
# 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"
|
|
||||||
# ]
|
|
||||||
|
|
||||||
sharejs_doc.on "externalUpdate", () =>
|
sharejs_doc.on "externalUpdate", () =>
|
||||||
#TODO!!!
|
@ide.showGenericMessageModal(
|
||||||
# Modal.createModal
|
"Document Updated Externally"
|
||||||
# title: "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."
|
||||||
# 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"
|
|
||||||
# ]
|
|
||||||
|
|
||||||
_unbindFromDocumentEvents: (document) ->
|
_unbindFromDocumentEvents: (document) ->
|
||||||
document.off()
|
document.off()
|
||||||
|
|
|
@ -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."
|
||||||
|
]
|
|
@ -204,16 +204,16 @@ define [
|
||||||
_getColorScheme: (hue) ->
|
_getColorScheme: (hue) ->
|
||||||
if @_isDarkTheme()
|
if @_isDarkTheme()
|
||||||
return {
|
return {
|
||||||
cursor: "hsl(#{hue}, 100%, 50%)"
|
cursor: "hsl(#{hue}, 70%, 50%)"
|
||||||
labelBackgroundColor: "hsl(#{hue}, 100%, 50%)"
|
labelBackgroundColor: "hsl(#{hue}, 70%, 50%)"
|
||||||
highlightBackgroundColor: "hsl(#{hue}, 100%, 28%);"
|
highlightBackgroundColor: "hsl(#{hue}, 100%, 28%);"
|
||||||
strikeThroughBackgroundColor: "hsl(#{hue}, 100%, 20%);"
|
strikeThroughBackgroundColor: "hsl(#{hue}, 100%, 20%);"
|
||||||
strikeThroughForegroundColor: "hsl(#{hue}, 100%, 60%);"
|
strikeThroughForegroundColor: "hsl(#{hue}, 100%, 60%);"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return {
|
return {
|
||||||
cursor: "hsl(#{hue}, 100%, 50%)"
|
cursor: "hsl(#{hue}, 70%, 50%)"
|
||||||
labelBackgroundColor: "hsl(#{hue}, 100%, 50%)"
|
labelBackgroundColor: "hsl(#{hue}, 70%, 50%)"
|
||||||
highlightBackgroundColor: "hsl(#{hue}, 70%, 85%);"
|
highlightBackgroundColor: "hsl(#{hue}, 70%, 85%);"
|
||||||
strikeThroughBackgroundColor: "hsl(#{hue}, 70%, 95%);"
|
strikeThroughBackgroundColor: "hsl(#{hue}, 70%, 95%);"
|
||||||
strikeThroughForegroundColor: "hsl(#{hue}, 70%, 40%);"
|
strikeThroughForegroundColor: "hsl(#{hue}, 70%, 40%);"
|
||||||
|
|
|
@ -5,6 +5,7 @@ define [
|
||||||
"ide/file-tree/controllers/FileTreeController"
|
"ide/file-tree/controllers/FileTreeController"
|
||||||
"ide/file-tree/controllers/FileTreeEntityController"
|
"ide/file-tree/controllers/FileTreeEntityController"
|
||||||
"ide/file-tree/controllers/FileTreeFolderController"
|
"ide/file-tree/controllers/FileTreeFolderController"
|
||||||
|
"ide/file-tree/controllers/FileTreeRootFolderController"
|
||||||
], () ->
|
], () ->
|
||||||
class FileTreeManager
|
class FileTreeManager
|
||||||
constructor: (@ide, @$scope) ->
|
constructor: (@ide, @$scope) ->
|
||||||
|
@ -59,6 +60,7 @@ define [
|
||||||
@ide.socket.on "reciveEntityMove", (entity_id, folder_id) =>
|
@ide.socket.on "reciveEntityMove", (entity_id, folder_id) =>
|
||||||
entity = @findEntityById(entity_id)
|
entity = @findEntityById(entity_id)
|
||||||
folder = @findEntityById(folder_id)
|
folder = @findEntityById(folder_id)
|
||||||
|
console.log "Got recive ENTITY", entity_id, folder_id, entity, folder
|
||||||
@$scope.$apply () =>
|
@$scope.$apply () =>
|
||||||
@_moveEntityInScope(entity, folder)
|
@_moveEntityInScope(entity, folder)
|
||||||
|
|
||||||
|
@ -68,7 +70,15 @@ define [
|
||||||
entity.selected = false
|
entity.selected = false
|
||||||
entity.selected = true
|
entity.selected = true
|
||||||
|
|
||||||
|
findSelectedEntity: () ->
|
||||||
|
selected = null
|
||||||
|
@forEachEntity (entity) ->
|
||||||
|
selected = entity if entity.selected
|
||||||
|
return selected
|
||||||
|
|
||||||
findEntityById: (id, options = {}) ->
|
findEntityById: (id, options = {}) ->
|
||||||
|
return @$scope.rootFolder if @$scope.rootFolder.id == id
|
||||||
|
|
||||||
entity = @_findEntityByIdInFolder @$scope.rootFolder, id
|
entity = @_findEntityByIdInFolder @$scope.rootFolder, id
|
||||||
return entity if entity?
|
return entity if entity?
|
||||||
|
|
||||||
|
@ -250,7 +260,7 @@ define [
|
||||||
_csrf: window.csrfToken
|
_csrf: window.csrfToken
|
||||||
}
|
}
|
||||||
|
|
||||||
_deleteEntityFromScope: (entity) ->
|
_deleteEntityFromScope: (entity, options = { moveToDeleted: true }) ->
|
||||||
parent_folder = null
|
parent_folder = null
|
||||||
@forEachEntity (possible_entity, folder) ->
|
@forEachEntity (possible_entity, folder) ->
|
||||||
if possible_entity == entity
|
if possible_entity == entity
|
||||||
|
@ -261,11 +271,11 @@ define [
|
||||||
if index > -1
|
if index > -1
|
||||||
parent_folder.children.splice(index, 1)
|
parent_folder.children.splice(index, 1)
|
||||||
|
|
||||||
if entity.type == "doc"
|
if entity.type == "doc" and options.moveToDeleted
|
||||||
entity.deleted = true
|
entity.deleted = true
|
||||||
@$scope.deletedDocs.push entity
|
@$scope.deletedDocs.push entity
|
||||||
|
|
||||||
_moveEntityInScope: (entity, parent_folder) ->
|
_moveEntityInScope: (entity, parent_folder) ->
|
||||||
return if entity in parent_folder.children
|
return if entity in parent_folder.children
|
||||||
@_deleteEntityFromScope(entity)
|
@_deleteEntityFromScope(entity, moveToDeleted: false)
|
||||||
parent_folder.children.push(entity)
|
parent_folder.children.push(entity)
|
||||||
|
|
|
@ -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)
|
||||||
|
]
|
|
@ -4,9 +4,11 @@ define [
|
||||||
App.directive "draggable", () ->
|
App.directive "draggable", () ->
|
||||||
return {
|
return {
|
||||||
link: (scope, element, attrs) ->
|
link: (scope, element, attrs) ->
|
||||||
element.draggable
|
scope.$watch attrs.draggable, (draggable) ->
|
||||||
delay: 250
|
if draggable
|
||||||
opacity: 0.7
|
element.draggable
|
||||||
helper: "clone"
|
delay: 250
|
||||||
scroll: true
|
opacity: 0.7
|
||||||
|
helper: "clone"
|
||||||
|
scroll: true
|
||||||
}
|
}
|
|
@ -7,9 +7,11 @@ define [
|
||||||
onDropCallback: "="
|
onDropCallback: "="
|
||||||
}
|
}
|
||||||
link: (scope, element, attrs) ->
|
link: (scope, element, attrs) ->
|
||||||
element.droppable
|
scope.$watch attrs.droppable, (droppable) ->
|
||||||
greedy: true
|
if droppable
|
||||||
hoverClass: "droppable-hover"
|
element.droppable
|
||||||
accept: attrs.accept
|
greedy: true
|
||||||
drop: scope.onDropCallback
|
hoverClass: "droppable-hover"
|
||||||
|
accept: attrs.accept
|
||||||
|
drop: scope.onDropCallback
|
||||||
}
|
}
|
|
@ -6,10 +6,18 @@ define [
|
||||||
restrict: "E"
|
restrict: "E"
|
||||||
scope: {
|
scope: {
|
||||||
entity: "="
|
entity: "="
|
||||||
|
permissions: "="
|
||||||
}
|
}
|
||||||
templateUrl: "entityListItemTemplate"
|
templateUrl: "entityListItemTemplate"
|
||||||
compile: (element) ->
|
compile: (element) ->
|
||||||
RecursionHelper.compile element, (scope, element, attrs, ctrl) ->
|
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);
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -56,7 +56,7 @@ define [
|
||||||
OWN_HUE: 200 # We will always appear as this color to ourselves
|
OWN_HUE: 200 # We will always appear as this color to ourselves
|
||||||
ANONYMOUS_HUE: 100
|
ANONYMOUS_HUE: 100
|
||||||
getHueForUserId: (user_id) ->
|
getHueForUserId: (user_id) ->
|
||||||
if !user_id?
|
if !user_id? or user_id == "anonymous-user"
|
||||||
return @ANONYMOUS_HUE
|
return @ANONYMOUS_HUE
|
||||||
|
|
||||||
if window.user.id == user_id
|
if window.user.id == user_id
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -3,7 +3,7 @@ define [
|
||||||
], (App) ->
|
], (App) ->
|
||||||
# We create and provide this as service so that we can access the global ide
|
# We create and provide this as service so that we can access the global ide
|
||||||
# from within other parts of the angular app.
|
# from within other parts of the angular app.
|
||||||
App.factory "ide", ["$http", ($http) ->
|
App.factory "ide", ["$http", "$modal", ($http, $modal) ->
|
||||||
ide = {}
|
ide = {}
|
||||||
ide.$http = $http
|
ide.$http = $http
|
||||||
|
|
||||||
|
@ -16,5 +16,22 @@ define [
|
||||||
ide.showGenericServerErrorMessage = () ->
|
ide.showGenericServerErrorMessage = () ->
|
||||||
console.error "GENERIC SERVER ERROR MESSAGE STUB"
|
console.error "GENERIC SERVER ERROR MESSAGE STUB"
|
||||||
|
|
||||||
|
ide.showGenericMessageModal = (title, message) ->
|
||||||
|
$modal.open {
|
||||||
|
templateUrl: "genericMessageModalTemplate"
|
||||||
|
controller: "GenericMessageModalController"
|
||||||
|
resolve:
|
||||||
|
title: -> title
|
||||||
|
message: -> message
|
||||||
|
}
|
||||||
|
|
||||||
return ide
|
return ide
|
||||||
]
|
]
|
||||||
|
|
||||||
|
App.controller "GenericMessageModalController", ["$scope", "$modalInstance", "title", "message", ($scope, $modalInstance, title, message) ->
|
||||||
|
$scope.title = title
|
||||||
|
$scope.message = message
|
||||||
|
|
||||||
|
$scope.done = () ->
|
||||||
|
$modalInstance.close()
|
||||||
|
]
|
||||||
|
|
|
@ -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"
|
||||||
|
]
|
|
@ -1,5 +1,7 @@
|
||||||
define [
|
define [
|
||||||
"ide/settings/services/settings"
|
"ide/settings/services/settings"
|
||||||
"ide/settings/controllers/SettingsController"
|
"ide/settings/controllers/SettingsController"
|
||||||
|
"ide/settings/controllers/ProjectNameController"
|
||||||
|
|
||||||
], () ->
|
], () ->
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,9 @@ define [
|
||||||
|
|
||||||
@$scope.toggleTrackChanges = () =>
|
@$scope.toggleTrackChanges = () =>
|
||||||
if @$scope.ui.view == "track-changes"
|
if @$scope.ui.view == "track-changes"
|
||||||
@$scope.ui.view = "editor"
|
@hide()
|
||||||
else
|
else
|
||||||
@$scope.ui.view = "track-changes"
|
@show()
|
||||||
@onShow()
|
|
||||||
|
|
||||||
@$scope.$watch "trackChanges.selection.updates", (updates) =>
|
@$scope.$watch "trackChanges.selection.updates", (updates) =>
|
||||||
if updates? and updates.length > 0
|
if updates? and updates.length > 0
|
||||||
|
@ -24,11 +23,14 @@ define [
|
||||||
@$scope.trackChanges.selection.doc = entity
|
@$scope.trackChanges.selection.doc = entity
|
||||||
@reloadDiff()
|
@reloadDiff()
|
||||||
|
|
||||||
onShow: () ->
|
show: () ->
|
||||||
|
@$scope.ui.view = "track-changes"
|
||||||
@reset()
|
@reset()
|
||||||
# @fetchNextBatchOfChanges()
|
|
||||||
# .success () =>
|
hide: () ->
|
||||||
# @autoSelectRecentUpdates()
|
@$scope.ui.view = "editor"
|
||||||
|
# Make sure we run the 'open' logic for whatever is currently selected
|
||||||
|
@$scope.$emit "entity:selected", @ide.fileTreeManager.findSelectedEntity()
|
||||||
|
|
||||||
reset: () ->
|
reset: () ->
|
||||||
@$scope.trackChanges = {
|
@$scope.trackChanges = {
|
||||||
|
@ -157,21 +159,24 @@ define [
|
||||||
}
|
}
|
||||||
|
|
||||||
if entry.i? or entry.d?
|
if entry.i? or entry.d?
|
||||||
name = "#{entry.meta.user.first_name} #{entry.meta.user.last_name}"
|
if entry.meta.user?
|
||||||
if entry.meta.user.id == @$scope.user.id
|
name = "#{entry.meta.user.first_name} #{entry.meta.user.last_name}"
|
||||||
|
else
|
||||||
|
name = "Anonymous"
|
||||||
|
if entry.meta.user?.id == @$scope.user.id
|
||||||
name = "you"
|
name = "you"
|
||||||
date = moment(entry.meta.end_ts).format("Do MMM YYYY, h:mm a")
|
date = moment(entry.meta.end_ts).format("Do MMM YYYY, h:mm a")
|
||||||
if entry.i?
|
if entry.i?
|
||||||
highlights.push {
|
highlights.push {
|
||||||
label: "Added by #{name} on #{date}"
|
label: "Added by #{name} on #{date}"
|
||||||
highlight: range
|
highlight: range
|
||||||
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user.id)
|
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user?.id)
|
||||||
}
|
}
|
||||||
else if entry.d?
|
else if entry.d?
|
||||||
highlights.push {
|
highlights.push {
|
||||||
label: "Deleted by #{name} on #{date}"
|
label: "Deleted by #{name} on #{date}"
|
||||||
strikeThrough: range
|
strikeThrough: range
|
||||||
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user.id)
|
hue: @ide.onlineUsersManager.getHueForUserId(entry.meta.user?.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {text, highlights}
|
return {text, highlights}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
@import "./editor/pdf.less";
|
@import "./editor/pdf.less";
|
||||||
@import "./editor/share.less";
|
@import "./editor/share.less";
|
||||||
@import "./editor/chat.less";
|
@import "./editor/chat.less";
|
||||||
|
@import "./editor/binary-file.less";
|
||||||
|
|
||||||
.full-size {
|
.full-size {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -17,10 +18,15 @@
|
||||||
.global-alerts {
|
.global-alerts {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
top: (@line-height-computed / 4);
|
top: 2px;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
margin-left: -200px;
|
margin-left: -200px;
|
||||||
|
.alert {
|
||||||
|
padding: (@line-height-computed / 4);
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: (@line-height-computed / 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#chat-wrapper {
|
#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
|
// The internal components of the aceEditor directive
|
||||||
.ace-editor-wrapper {
|
.ace-editor-wrapper {
|
||||||
.full-size;
|
.full-size;
|
||||||
|
|
20
services/web/public/stylesheets/app/editor/binary-file.less
Normal file
20
services/web/public/stylesheets/app/editor/binary-file.less
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,6 +9,10 @@ aside#file-tree {
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
&.no-toolbar {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
|
|
|
@ -73,18 +73,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-btn {
|
.toolbar {
|
||||||
position: relative;
|
.log-btn {
|
||||||
.label {
|
position: relative;
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: .15em .6em .2em;
|
|
||||||
font-size: 60%;
|
|
||||||
}
|
|
||||||
&.active, &:active {
|
|
||||||
.label {
|
.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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,6 @@
|
||||||
color: @gray-dark;
|
color: @gray-dark;
|
||||||
text-decoration: none;
|
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 {
|
.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 {
|
&.toolbar-header {
|
||||||
box-shadow: 0 0 2px #ccc;
|
box-shadow: 0 0 2px #ccc;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
@ -9,117 +9,25 @@
|
||||||
@range-bar-selected-offset: 14px;
|
@range-bar-selected-offset: 14px;
|
||||||
|
|
||||||
#trackChanges {
|
#trackChanges {
|
||||||
// .track-changes-diff {
|
.upgrade-prompt {
|
||||||
// position: absolute;
|
position: absolute;
|
||||||
// right: @changesListWidth + 1px;
|
top: 0;
|
||||||
// left: 0;
|
bottom: 0;
|
||||||
// top: 0;
|
left: 0;
|
||||||
// bottom: 0;
|
right: 0;
|
||||||
// height: 100%;
|
z-index: 100;
|
||||||
// .ace_editor {
|
background-color: rgba(128,128,128,0.4);
|
||||||
// position: absolute;
|
.message {
|
||||||
// top: 42px;
|
margin: auto;
|
||||||
// left: 0;
|
margin-top: 100px;
|
||||||
// right: 0;
|
padding: 10px 10px 14px 10px;
|
||||||
// bottom: 0;
|
width: 500px;
|
||||||
// .ace_active-line, .ace_cursor-layer, .ace_gutter-active-line {
|
font-weight: bold;
|
||||||
// display: none;
|
text-align: center;
|
||||||
// }
|
background-color: white;
|
||||||
// }
|
border-radius: 8px;
|
||||||
// .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);
|
|
||||||
// }
|
|
||||||
|
|
||||||
.diff {
|
.diff {
|
||||||
margin-right: @changesListWidth;
|
margin-right: @changesListWidth;
|
||||||
|
|
Loading…
Reference in a new issue