|
|
@@ -1,189 +0,0 @@
|
|
|
-import App from '../../../base'
|
|
|
-
|
|
|
-export default App.controller(
|
|
|
- 'BinaryFileController',
|
|
|
- function ($scope, $rootScope, $http, $timeout, $element, ide, waitFor) {
|
|
|
- const MAX_FILE_SIZE = 2 * 1024 * 1024
|
|
|
- const MAX_URL_LENGTH = 60
|
|
|
- const FRONT_OF_URL_LENGTH = 35
|
|
|
- const FILLER = '...'
|
|
|
- const TAIL_OF_URL_LENGTH =
|
|
|
- MAX_URL_LENGTH - FRONT_OF_URL_LENGTH - FILLER.length
|
|
|
-
|
|
|
- const textExtensions = window.ExposedSettings.textExtensions
|
|
|
- const imageExtensions = ['png', 'jpg', 'jpeg', 'gif']
|
|
|
- const previewableExtensions = []
|
|
|
-
|
|
|
- const extension = file => file.name.split('.').pop().toLowerCase()
|
|
|
-
|
|
|
- $scope.isTextFile = () =>
|
|
|
- textExtensions.indexOf(extension($scope.openFile)) > -1
|
|
|
- $scope.isImageFile = () =>
|
|
|
- imageExtensions.indexOf(extension($scope.openFile)) > -1
|
|
|
- $scope.isPreviewableFile = () =>
|
|
|
- previewableExtensions.indexOf(extension($scope.openFile)) > -1
|
|
|
- $scope.isUnpreviewableFile = () =>
|
|
|
- !$scope.isTextFile() &&
|
|
|
- !$scope.isImageFile() &&
|
|
|
- !$scope.isPreviewableFile()
|
|
|
-
|
|
|
- $scope.textPreview = {
|
|
|
- loading: false,
|
|
|
- shouldShowDots: false,
|
|
|
- error: false,
|
|
|
- data: null,
|
|
|
- }
|
|
|
-
|
|
|
- $scope.refreshing = false
|
|
|
- $scope.refreshError = null
|
|
|
-
|
|
|
- $scope.displayUrl = function (url) {
|
|
|
- if (url == null) {
|
|
|
- return
|
|
|
- }
|
|
|
- if (url.length > MAX_URL_LENGTH) {
|
|
|
- const front = url.slice(0, FRONT_OF_URL_LENGTH)
|
|
|
- const tail = url.slice(url.length - TAIL_OF_URL_LENGTH)
|
|
|
- return front + FILLER + tail
|
|
|
- }
|
|
|
- return url
|
|
|
- }
|
|
|
-
|
|
|
- $scope.refreshFile = function (file) {
|
|
|
- $scope.refreshing = true
|
|
|
- $scope.refreshError = null
|
|
|
- window.expectingLinkedFileRefreshedSocketFor = file.name
|
|
|
- ide.fileTreeManager
|
|
|
- .refreshLinkedFile(file)
|
|
|
- .then(function (response) {
|
|
|
- const { data } = response
|
|
|
- const newFileId = data.new_file_id
|
|
|
- $timeout(
|
|
|
- () =>
|
|
|
- waitFor(() => ide.fileTreeManager.findEntityById(newFileId), 5000)
|
|
|
- .then(newFile => {
|
|
|
- ide.binaryFilesManager.openFile(newFile)
|
|
|
- window.expectingLinkedFileRefreshedSocketFor = null
|
|
|
- })
|
|
|
- .catch(err => console.warn(err)),
|
|
|
-
|
|
|
- 0
|
|
|
- )
|
|
|
- $scope.refreshError = null
|
|
|
- })
|
|
|
- .catch(response => ($scope.refreshError = response.data))
|
|
|
- .finally(() => {
|
|
|
- $scope.refreshing = false
|
|
|
- const provider = file.linkedFileData.provider
|
|
|
- if (
|
|
|
- provider === 'mendeley' ||
|
|
|
- provider === 'zotero' ||
|
|
|
- file.name.match(/^.*\.bib$/)
|
|
|
- ) {
|
|
|
- ide.$scope.$emit('references:should-reindex', {})
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- // Callback fired when the `img` tag fails to load,
|
|
|
- // `failedLoad` used to show the "No Preview" message
|
|
|
- $scope.failedLoad = false
|
|
|
- window.sl_binaryFilePreviewError = () => {
|
|
|
- $scope.failedLoad = true
|
|
|
- $scope.$apply()
|
|
|
- }
|
|
|
-
|
|
|
- // Callback fired when the `img` tag is done loading,
|
|
|
- // `imgLoaded` is used to show the spinner gif while loading
|
|
|
- $scope.imgLoaded = false
|
|
|
- window.sl_binaryFilePreviewLoaded = () => {
|
|
|
- $scope.imgLoaded = true
|
|
|
- $scope.$apply()
|
|
|
- }
|
|
|
-
|
|
|
- if ($scope.isTextFile()) {
|
|
|
- loadTextFilePreview()
|
|
|
- }
|
|
|
-
|
|
|
- function loadTextFilePreview() {
|
|
|
- const url = `/project/${window.project_id}/file/${$scope.openFile.id}`
|
|
|
- let truncated = false
|
|
|
- displayPreviewLoading()
|
|
|
- getFileSize(url)
|
|
|
- .then(fileSize => {
|
|
|
- const opts = {}
|
|
|
- if (fileSize > MAX_FILE_SIZE) {
|
|
|
- truncated = true
|
|
|
- opts.maxSize = MAX_FILE_SIZE
|
|
|
- }
|
|
|
- return getFileContents(url, opts)
|
|
|
- })
|
|
|
- .then(contents => {
|
|
|
- const displayedContents = truncated
|
|
|
- ? truncateFileContents(contents)
|
|
|
- : contents
|
|
|
- displayPreview(displayedContents, truncated)
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- console.error(err)
|
|
|
- displayPreviewError()
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- function getFileSize(url) {
|
|
|
- return $http.head(url).then(response => {
|
|
|
- const size = parseInt(response.headers('Content-Length'), 10)
|
|
|
- if (isNaN(size)) {
|
|
|
- throw new Error('Could not parse Content-Length header')
|
|
|
- }
|
|
|
- return size
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- function getFileContents(url, opts = {}) {
|
|
|
- const { maxSize } = opts
|
|
|
- if (maxSize != null) {
|
|
|
- url += `?range=0-${maxSize}`
|
|
|
- }
|
|
|
- return $http
|
|
|
- .get(url, {
|
|
|
- transformResponse: null, // Don't parse JSON
|
|
|
- })
|
|
|
- .then(response => {
|
|
|
- return response.data
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- function truncateFileContents(contents) {
|
|
|
- return contents.replace(/\n.*$/, '')
|
|
|
- }
|
|
|
-
|
|
|
- function displayPreviewLoading() {
|
|
|
- $scope.textPreview.data = null
|
|
|
- $scope.textPreview.loading = true
|
|
|
- $scope.textPreview.shouldShowDots = false
|
|
|
- $scope.$apply()
|
|
|
- }
|
|
|
-
|
|
|
- function displayPreview(contents, truncated) {
|
|
|
- $scope.textPreview.error = false
|
|
|
- $scope.textPreview.data = contents
|
|
|
- $scope.textPreview.shouldShowDots = truncated
|
|
|
- $timeout(setPreviewHeight, 0)
|
|
|
- }
|
|
|
-
|
|
|
- function displayPreviewError() {
|
|
|
- $scope.textPreview.error = true
|
|
|
- $scope.textPreview.loading = false
|
|
|
- }
|
|
|
-
|
|
|
- function setPreviewHeight() {
|
|
|
- const $preview = $element.find('.text-preview .scroll-container')
|
|
|
- const $header = $element.find('.binary-file-header')
|
|
|
- const maxHeight = $element.height() - $header.height() - 14 // borders + margin
|
|
|
- $preview.css({ 'max-height': maxHeight })
|
|
|
- // Don't show the preview until we've set the height, otherwise we jump around
|
|
|
- $scope.textPreview.loading = false
|
|
|
- }
|
|
|
- }
|
|
|
-)
|