Browse Source

webpage title & file downloads & progress bars

master
Eduard Kuzmenko 5 years ago
parent
commit
427718d852
  1. 19
      package-lock.json
  2. 4
      package.json
  3. 22
      src/components/pageSignUp.ts
  4. 37
      src/components/wrappers.ts
  5. 40
      src/lib/appManagers/appDocsManager.ts
  6. 4
      src/lib/appManagers/appImManager.ts
  7. 5
      src/lib/appManagers/appMediaViewer.ts
  8. 68
      src/lib/appManagers/appPhotosManager.ts
  9. 100
      src/lib/filemanager.ts
  10. 5
      src/lib/lottieLoader.ts
  11. 40
      src/lib/mtproto/apiFileManager.ts
  12. 8
      src/scss/partials/_sidebar.scss
  13. 42
      src/scss/style.scss
  14. 1
      webpack.dev.js
  15. 2
      webpack.prod.js

19
package-lock.json generated

@ -6521,9 +6521,10 @@ @@ -6521,9 +6521,10 @@
}
},
"lottie-web": {
"version": "5.6.3",
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.6.3.tgz",
"integrity": "sha512-cSG6kSA2m5ppxV/QMVHRVGop/R+oXgO4vVMvDcZR015Cy0PGml5hHP+XG21yB2qV6cYZy+X3ChTogSALgch7CA=="
"version": "5.6.4",
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.6.4.tgz",
"integrity": "sha512-eU+21Wo/RSi4i260S7fDUxfhNJ9PhfzUJMVQpip0yZd19oJ18jrNCoSQKVUzjC2TzOjqumlLZXR636ezKoWNQg==",
"dev": true
},
"loud-rejection": {
"version": "1.6.0",
@ -12816,6 +12817,12 @@ @@ -12816,6 +12817,12 @@
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
"dev": true
},
"streamsaver": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/streamsaver/-/streamsaver-2.0.3.tgz",
"integrity": "sha512-IpXeZ67YxcsrfZHe3yg/IyZ5KPfRSn1teDy5mRX2e8M6K410NcJNcR+SFQ2Z92DO36VBUArQP4Vy3Qu33MwIOQ==",
"dev": true
},
"string-length": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
@ -13761,6 +13768,12 @@ @@ -13761,6 +13768,12 @@
"minimalistic-assert": "^1.0.0"
}
},
"web-streams-polyfill": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-2.0.6.tgz",
"integrity": "sha512-nXOi4fBykO4LzyQhZX3MAGib635KGZBoNTkNXrNIkz0zthEf2QokEWxRb0H632xNLDWtHFb1R6dFGzksjYMSDw==",
"dev": true
},
"webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",

4
package.json

@ -14,7 +14,6 @@ @@ -14,7 +14,6 @@
"license": "ISC",
"dependencies": {
"jsbn": "^1.1.0",
"lottie-web": "^5.6.3",
"materialize-css": "^1.0.0",
"roboto-fontface": "^0.10.0",
"rusha": "^0.8.13",
@ -41,6 +40,7 @@ @@ -41,6 +40,7 @@
"install": "^0.13.0",
"jest": "^24.9.0",
"leemon": "^6.2.0",
"lottie-web": "^5.6.4",
"node-sass": "^4.13.0",
"npm": "^6.13.4",
"offscreen-canvas": "^0.1.1",
@ -49,11 +49,13 @@ @@ -49,11 +49,13 @@
"pako": "^1.0.10",
"resolve-url-loader": "^3.1.1",
"sass-loader": "^8.0.0",
"streamsaver": "^2.0.3",
"style-loader": "^1.0.0",
"ts-jest": "^24.3.0",
"ts-loader": "^6.2.1",
"typescript": "^3.7.2",
"url-loader": "^2.2.0",
"web-streams-polyfill": "^2.0.6",
"webp-hero": "0.0.0-dev.24",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",

22
src/components/pageSignUp.ts

@ -9,6 +9,7 @@ let authCode: { @@ -9,6 +9,7 @@ let authCode: {
import resizeableImage from '../lib/cropper';
import pageIm from './pageIm';
import apiManager from '../lib/mtproto/apiManager';
import apiFileManager from '../lib/mtproto/apiFileManager';
export default (_authCode: typeof authCode) => {
authCode = _authCode;
@ -72,19 +73,6 @@ export default (_authCode: typeof authCode) => { @@ -72,19 +73,6 @@ export default (_authCode: typeof authCode) => {
return;
}
/* console.log(file, typeof(file)); */
// @ts-ignore
/* apiFileManager.uploadFile(file).then(function(inputFile) {
console.log('uploaded smthn', inputFile);
apiManager.invokeApi('photos.uploadProfilePhoto', {
file: inputFile
}).then(function (updateResult) {
console.log('updated photo!');
});
}); */
var reader = new FileReader();
reader.onload = (e) => {
var contents = e.target.result as string;
@ -94,18 +82,11 @@ export default (_authCode: typeof authCode) => { @@ -94,18 +82,11 @@ export default (_authCode: typeof authCode) => {
avatarImage.src = contents;
avatarImage.onload = () => {
/* avatarPreviewCtx.drawImage(avatarImage,
70, 20, // Start at 70/20 pixels from the left and the top of the image (crop),
50, 50, // "Get" a `50 * 50` (w * h) area from the source image (crop),
0, 0, // Place the result at 0, 0 in the canvas,
100, 100); // With as width / height: 100 * 100 (scale) */
cropper = resizeableImage(avatarImage, avatarPreview);
avatarInput.value = '';
};
avatarPopup.classList.add('active');
//console.log(contents);
};
reader.readAsDataURL(file);
@ -136,7 +117,6 @@ export default (_authCode: typeof authCode) => { @@ -136,7 +117,6 @@ export default (_authCode: typeof authCode) => {
}
console.log('invoking uploadFile...');
// @ts-ignore
apiFileManager.uploadFile(avatarBlob).then((inputFile: any) => {
console.log('uploaded smthn', inputFile);

37
src/components/wrappers.ts

@ -7,7 +7,7 @@ import {AppImManager} from "../lib/appManagers/appImManager"; @@ -7,7 +7,7 @@ import {AppImManager} from "../lib/appManagers/appImManager";
import { formatBytes } from "../lib/utils";
import ProgressivePreloader from './preloader';
import LazyLoadQueue from './lazyLoadQueue';
import apiFileManager from '../lib/mtproto/apiFileManager';
import apiFileManager, { CancellablePromise } from '../lib/mtproto/apiFileManager';
import appWebpManager from '../lib/appManagers/appWebpManager';
import {wrapPlayer} from '../lib/ckin';
@ -190,10 +190,45 @@ export function wrapDocument(doc: MTDocument, withTime = false): HTMLDivElement @@ -190,10 +190,45 @@ export function wrapDocument(doc: MTDocument, withTime = false): HTMLDivElement
docDiv.innerHTML = `
<div class="document-ico ext-${ext}">${ext2}</div>
<div class="document-download"><div class="tgico-download"></div></div>
<div class="document-name">${fileName}</div>
<div class="document-size">${size}</div>
`;
let downloadDiv = docDiv.querySelector('.document-download') as HTMLDivElement;
let preloader: ProgressivePreloader;
let promise: CancellablePromise<Blob>;
docDiv.addEventListener('click', () => {
if(!promise) {
if(!preloader) {
preloader = new ProgressivePreloader(downloadDiv, true);
} else {
preloader.attach(downloadDiv, true);
}
promise = appDocsManager.saveDocFile(doc.id);
promise.notify = (details: {done: number, total: number}) => {
console.log('docDiv download', promise, details);
let percents = details.done / details.total * 100;
preloader.setProgress(percents);
};
downloadDiv.classList.add('downloading');
promise.then(() => {
downloadDiv.classList.remove('downloading');
preloader.detach();
downloadDiv.remove();
});
} else {
downloadDiv.classList.remove('downloading');
promise.cancel();
preloader.detach();
promise = null;
}
});
return docDiv;
}

40
src/lib/appManagers/appDocsManager.ts

@ -233,26 +233,36 @@ class AppDocsManager { @@ -233,26 +233,36 @@ class AppDocsManager {
//historyDoc.progress.cancel = downloadPromise.cancel;
console.log('return downloadPromise:', downloadPromise);
return downloadPromise;
}
/* public saveDocFile(docID: string) {
var doc = this.docs[docID]
var historyDoc = this.docsForHistory[docID] || doc || {}
var mimeType = doc.mime_type
var fileName = this.getFileName(doc)
var ext = (fileName.split('.', 2) || [])[1] || ''
public saveDocFile(docID: string): CancellablePromise<Blob> {
var doc = this.docs[docID];
var fileName = this.getFileName(doc);
var ext = (fileName.split('.', 2) || [])[1] || '';
try {
let writer = FileManager.chooseSaveFile(fileName, ext, doc.mime_type, doc.size);
return writer.ready.then(() => {
let promise = this.downloadDoc(docID, writer);
promise.then(() => {
writer.close();
console.log('saved doc', doc);
});
FileManager.chooseSave(this.getFileName(doc), ext, doc.mime_type).then((writableFileEntry) => {
if (writableFileEntry) {
this.downloadDoc(docID, writableFileEntry)
}
}, () => {
this.downloadDoc(docID).then((blob) => {
return promise;
});
} catch(err) {
let promise = this.downloadDoc(docID);
promise.then((blob) => {
FileManager.download(blob, doc.mime_type, fileName)
})
})
} */
});
return promise;
}
}
}
export default new AppDocsManager();

4
src/lib/appManagers/appImManager.ts

@ -1726,7 +1726,9 @@ export class AppImManager { @@ -1726,7 +1726,9 @@ export class AppImManager {
textDiv.innerHTML = RichTextProcessor.wrapRichText(webpage.description);
}
//textDiv.innerText = webpage.description || '';
if(webpage.title) {
titleDiv.innerHTML = RichTextProcessor.wrapRichText(webpage.title);
}
quote.append(nameEl, titleDiv, textDiv);
box.append(quote);

5
src/lib/appManagers/appMediaViewer.ts

@ -66,6 +66,11 @@ export class AppMediaViewer { @@ -66,6 +66,11 @@ export class AppMediaViewer {
this.buttons.next.style.display = 'none';
}
});
this.buttons.download.addEventListener('click', () => {
let message = appMessagesManager.getMessage(this.currentMessageID);
appPhotosManager.downloadPhoto(message.media.photo.id);
});
/* this.buttons.prev.onclick = (e) => {
let history = appSidebarRight.historiesStorage[$rootScope.selectedPeerID]['inputMessagesFilterPhotoVideo'].slice();

68
src/lib/appManagers/appPhotosManager.ts

@ -283,7 +283,7 @@ export class AppPhotosManager { @@ -283,7 +283,7 @@ export class AppPhotosManager {
return photo;
}
public wrapForFull(photoID: string) {
/* public wrapForFull(photoID: string) {
var photo = this.wrapForHistory(photoID);
var fullWidth = document.body.scrollWidth - (Config.Mobile ? 0 : 32);
var fullHeight = document.body.scrollHeight - (Config.Mobile ? 0 : 116);
@ -310,38 +310,6 @@ export class AppPhotosManager { @@ -310,38 +310,6 @@ export class AppPhotosManager {
photo.full = full;
return photo;
}
/* public openPhoto(photoID: number, list: any) {
if(!photoID || photoID === '0') {
return false;
}
var scope = $rootScope.$new(true);
scope.photoID = photoID;
var controller = 'PhotoModalController';
if (list && list.p > 0) {
controller = 'UserpicModalController';
scope.userID = list.p;
} else if (list && list.p < 0) {
controller = 'ChatpicModalController';
scope.chatID = -list.p;
} else if (list && list.m > 0) {
scope.messageID = list.m;
if (list.w) {
scope.webpageID = list.w;
}
}
var modalInstance = $modal.open({
templateUrl: templateUrl('photo_modal'),
windowTemplateUrl: templateUrl('media_modal_layout'),
controller: controller,
scope: scope,
windowClass: 'photo_modal_window'
});
} */
public downloadPhoto(photoID: string) {
@ -349,28 +317,36 @@ export class AppPhotosManager { @@ -349,28 +317,36 @@ export class AppPhotosManager {
var ext = 'jpg';
var mimeType = 'image/jpeg';
var fileName = 'photo' + photoID + '.' + ext;
var fullWidth = Math.max(screen.width || 0, document.body.scrollWidth - 36, 800);
var fullHeight = Math.max(screen.height || 0, document.body.scrollHeight - 150, 800);
var fullWidth = this.windowW;
var fullHeight = this.windowH;
var fullPhotoSize = this.choosePhotoSize(photo, fullWidth, fullHeight);
var inputFileLocation = {
_: 'inputFileLocation',
volume_id: fullPhotoSize.location.volume_id,
local_id: fullPhotoSize.location.local_id,
secret: fullPhotoSize.location.secret
// @ts-ignore
_: photo._ == 'document' ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation',
id: photo.id,
access_hash: photo.access_hash,
file_reference: photo.file_reference,
thumb_size: fullPhotoSize.type
};
fileManager.chooseSaveFile(fileName, ext, mimeType).then((writableFileEntry) => {
if(writableFileEntry) {
try { // photo.dc_id, location, photoSize.size
let writer = fileManager.chooseSaveFile(fileName, ext, mimeType, fullPhotoSize.size);
writer.ready.then(() => {
console.log('ready');
apiFileManager.downloadFile(photo.dc_id, inputFileLocation, fullPhotoSize.size, {
mimeType: mimeType,
toFileEntry: writableFileEntry
toFileEntry: writer
}).then(() => {
// console.log('file save done')
writer.close();
//writer.abort();
console.log('file save done', fileName, ext, mimeType, writer);
}, (e: any) => {
console.log('photo download failed', e);
});
}
}, () => {
});
} catch(err) {
console.error('err', err);
var cachedBlob = apiFileManager.getCachedFile(inputFileLocation)
if (cachedBlob) {
return fileManager.download(cachedBlob, mimeType, fileName);
@ -382,7 +358,7 @@ export class AppPhotosManager { @@ -382,7 +358,7 @@ export class AppPhotosManager {
}, (e: any) => {
console.log('photo download failed', e);
});
});
}
}
}

100
src/lib/filemanager.ts

@ -1,9 +1,13 @@ @@ -1,9 +1,13 @@
import {bytesToArrayBuffer, blobSafeMimeType, blobConstruct, bytesToBase64} from './bin_utils';
class FileManager {
/* $window.URL = $window.URL || $window.webkitURL
$window.BlobBuilder = $window.BlobBuilder || $window.WebKitBlobBuilder || $window.MozBlobBuilder */
import 'web-streams-polyfill/ponyfill';
// @ts-ignore
import streamSaver from 'streamsaver';
if(window.location.href.indexOf('localhost') === -1) {
streamSaver.mitm = 'mitm.html';
}
class FileManager {
public isSafari = 'safari' in window;
public safariVersion = parseFloat(this.isSafari && (navigator.userAgent.match(/Version\/(\d+\.\d+).* Safari/) || [])[1]);
public safariWithDownload = this.isSafari && this.safariVersion >= 11.0;
@ -23,7 +27,7 @@ class FileManager { @@ -23,7 +27,7 @@ class FileManager {
return this.blobSupported;
}
public copy(fromFileEntry: any, toFileEntry: any) {
/* public copy(fromFileEntry: any, toFileEntry: any) {
return this.getFileWriter(toFileEntry).then((fileWriter) => {
return this.write(fileWriter, fromFileEntry).then(() => {
return fileWriter;
@ -36,9 +40,24 @@ class FileManager { @@ -36,9 +40,24 @@ class FileManager {
return Promise.reject(error);
});
});
} */
public copy(fromFileEntry: any, toFileEntry: any) {
return this.write(toFileEntry, fromFileEntry).then(() => {
console.log('copy success');
return toFileEntry;
}, (error: any) => {
console.error('copy error 1:', error);
try {
toFileEntry.truncate(0);
} catch(e) {
console.error('copy error', e);
}
public write(fileWriter: any, bytes: any) {
return Promise.reject(error);
});
}
/* public write(fileWriter: any, bytes: any) {
return new Promise((resolve, reject) => {
fileWriter.onwriteend = function(e: any) {
resolve();
@ -62,54 +81,52 @@ class FileManager { @@ -62,54 +81,52 @@ class FileManager {
}
}
});
}
} */
public chooseSaveFile(fileName: string, ext: string, mimeType: string) {
return Promise.reject();
/* if(!window.chrome || !chrome.fileSystem || !chrome.fileSystem.chooseEntry) {
//return qSync.reject()
return Promise.reject();
}
var deferred = $q.defer()
public write(fileWriter: any, bytes: any): Promise<void> {
if(bytes.file) {
return bytes.file((file: any) => {
return fileWriter.write(file);
});
} else if(bytes instanceof Blob) { // is file bytes
return new Promise((resolve, reject) => {
let fileReader = new FileReader();
fileReader.onload = function(event) {
let arrayBuffer = event.target.result as ArrayBuffer;
chrome.fileSystem.chooseEntry({
type: 'saveFile',
suggestedName: fileName,
accepts: [{
mimeTypes: [mimeType],
extensions: [ext]
}]
}, function (writableFileEntry) {
deferred.resolve(writableFileEntry)
})
let arr = new Uint8Array(arrayBuffer);
fileWriter.write(arr).then(resolve, reject);
};
return deferred.promise */
fileReader.readAsArrayBuffer(bytes);
});
} else {
//var blob = blobConstruct([bytesToArrayBuffer(bytes)]);
//return fileWriter.write(blob);
return fileWriter.write(bytes);
}
}
public getFileWriter(fileEntry: any) {
return new Promise((resolve, reject) => {
fileEntry.createWriter(resolve, reject);
public chooseSaveFile(fileName: string, ext: string, mimeType: string, size?: number): any {
let fileStream = streamSaver.createWriteStream(fileName, {
size: size,
writableStrategy: undefined,
readableStrategy: undefined
});
let writer = fileStream.getWriter();
return writer;
}
public getFakeFileWriter(mimeType: string, saveFileCallback: any) {
var blobParts: Array<Blob> = [];
var fakeFileWriter: any = {
write: (blob: Blob) => {
var fakeFileWriter = {
write: async(blob: Blob) => {
if(!this.blobSupported) {
if(fakeFileWriter.onerror) {
fakeFileWriter.onerror(new Error('Blob not supported by browser'));
}
return false;
throw false;
}
blobParts.push(blob);
setTimeout(() => {
if(fakeFileWriter.onwriteend) {
fakeFileWriter.onwriteend();
}
}, 0);
},
truncate: () => {
blobParts = [];
@ -277,6 +294,7 @@ class FileManager { @@ -277,6 +294,7 @@ class FileManager {
}, 100);
})
}
}
}
export default new FileManager();
export default new FileManager();

5
src/lib/lottieLoader.ts

@ -1,4 +1,7 @@ @@ -1,4 +1,7 @@
import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web";
//import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web";
// @ts-ignore
import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web/build/player/lottie_canvas.min.js";
//import LottiePlayer, { AnimationConfigWithPath, AnimationConfigWithData, AnimationItem } from "lottie-web/build/player/lottie_light.min.js";
import { isElementInViewport, isInDOM } from "./utils";
class LottieLoader {

40
src/lib/mtproto/apiFileManager.ts

@ -248,12 +248,12 @@ export class ApiFileManager { @@ -248,12 +248,12 @@ export class ApiFileManager {
return fileStorage.getFile(fileName, size);
}
public async downloadFile(dcID: number, location: any, size: number, options: {
public downloadFile(dcID: number, location: any, size: number, options: {
mimeType?: string,
dcID?: number,
toFileEntry?: any,
limitPart?: number
} = {}): Promise<Blob> {
} = {}): CancellablePromise<Blob> {
if(!FileManager.isAvailable()) {
return Promise.reject({type: 'BROWSER_BLOB_NOT_SUPPORTED'});
}
@ -288,19 +288,33 @@ export class ApiFileManager { @@ -288,19 +288,33 @@ export class ApiFileManager {
//this.log('downloadFile cachedPromise');
if(size) {
let blob = await cachedPromise;
/* let blob = await cachedPromise;
if(blob.size < size) {
this.log('downloadFile need to deleteFile, wrong size:', blob.size, size);
await this.deleteFile(location);
} else {
return cachedPromise;
} */
return cachedPromise.then((blob: Blob) => {
if(blob.size < size) {
this.log('downloadFile need to deleteFile, wrong size:', blob.size, size);
return this.deleteFile(location).then(() => {
return this.downloadFile(dcID, location, size, options);
}).catch(() => {
return this.downloadFile(dcID, location, size, options);
});
} else {
//return cachedPromise;
return blob;
}
});
} else {
return cachedPromise;
}
}
//this.log('arriba');
this.log('arriba');
//var deferred = $q.defer()
let deferredHelper: any = {notify: () => {}};
@ -310,16 +324,17 @@ export class ApiFileManager { @@ -310,16 +324,17 @@ export class ApiFileManager {
});
Object.assign(deferred, deferredHelper);
//return;
var canceled = false;
var resolved = false;
var mimeType = options.mimeType || 'image/jpeg',
cacheFileWriter: any;
var errorHandler = (error: any) => {
deferred.reject(error)
deferred.reject(error);
errorHandler = () => {};
if(cacheFileWriter &&
(!error || error.type != 'DOWNLOAD_CANCELED')) {
if(cacheFileWriter && (!error || error.type != 'DOWNLOAD_CANCELED')) {
cacheFileWriter.truncate(0);
}
};
@ -336,14 +351,15 @@ export class ApiFileManager { @@ -336,14 +351,15 @@ export class ApiFileManager {
if(toFileEntry) {
FileManager.copy(blob, toFileEntry).then(() => {
deferred.resolve();
}, errorHandler)
}, errorHandler);
} else {
deferred.resolve(this.cachedDownloads[fileName] = blob);
}
//}, () => {
}).catch(() => {
//this.log('not i wanted');
var fileWriterPromise = toFileEntry ? FileManager.getFileWriter(toFileEntry) : fileStorage.getFileWriter(fileName, mimeType);
//var fileWriterPromise = toFileEntry ? FileManager.getFileWriter(toFileEntry) : fileStorage.getFileWriter(fileName, mimeType);
var fileWriterPromise = toFileEntry ? Promise.resolve(toFileEntry) : fileStorage.getFileWriter(fileName, mimeType);
var processDownloaded = (bytes: any) => {
return Promise.resolve(bytes);
@ -414,7 +430,7 @@ export class ApiFileManager { @@ -414,7 +430,7 @@ export class ApiFileManager {
return Promise.resolve();
}
return processDownloaded(result.bytes).then((processedResult) => {
return processDownloaded(result.bytes).then((processedResult: Uint8Array) => {
return FileManager.write(fileWriter, processedResult).then(() => {
writeFileDeferred.resolve();
}, errorHandler).then(() => {
@ -427,7 +443,7 @@ export class ApiFileManager { @@ -427,7 +443,7 @@ export class ApiFileManager {
deferred.resolve(this.cachedDownloads[fileName] = fileWriter.finalize());
}
} else {
this.log('deferred notify 2:', {done: offset + limit, total: size});
this.log('deferred notify 2:', {done: offset + limit, total: size}, deferred);
deferred.notify({done: offset + limit, total: size});
}
});
@ -449,6 +465,8 @@ export class ApiFileManager { @@ -449,6 +465,8 @@ export class ApiFileManager {
}
};
console.log(deferred, deferred.notify, deferred.cancel);
if(!toFileEntry) {
this.cachedDownloadPromises[fileName] = deferred;
}

8
src/scss/partials/_sidebar.scss

@ -163,15 +163,17 @@ @@ -163,15 +163,17 @@
#content-docs {
padding: 15px;
padding-top: 3px;
.document {
padding-left: 5rem;
padding-right: 1rem;
height: 54px;
//height: 54px;
height: calc(54px + 1.5rem);
& + .document {
/* & + .document {
margin-top: 1.5rem;
}
} */
}
.document-name {

42
src/scss/style.scss

@ -61,11 +61,21 @@ button, input, optgroup, select, textarea, html { @@ -61,11 +61,21 @@ button, input, optgroup, select, textarea, html {
min-width: 100%;
}
.container {
margin: 0 auto;
}
h1, h2, h3, h4, h5, h6 {
letter-spacing: -.66px;
font-weight: 500;
}
h4 {
font-size: 2.28rem;
margin: 1.52rem 0 .912rem 0;
line-height: 110%;
}
input {
caret-color: $button-primary-background;
}
@ -388,7 +398,7 @@ input { @@ -388,7 +398,7 @@ input {
cursor: pointer;
position: relative;
.document-ico {
.document-ico, .document-download {
position: absolute;
left: 0;
width: 54px;
@ -404,6 +414,28 @@ input { @@ -404,6 +414,28 @@ input {
text-overflow: ellipsis;
}
.document-download {
z-index: 3;
background-color: rgb(101, 161, 227);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
cursor: pointer;
.tgico-download {
transform: scale(1);
transition: .2s scale;
}
&.downloading {
.tgico-download {
transform: scale(0);
}
}
}
&:not(.photo) {
.document-ico {
padding-top: 1.5rem;
@ -692,7 +724,7 @@ input { @@ -692,7 +724,7 @@ input {
text-align: left;
display: grid;
grid-template-columns: 15% 65% 20%;
grid-template-columns: 15% 60% 25%;
&:hover {
background-color: rgba(112, 117, 121, .08);
@ -1059,6 +1091,7 @@ span.popup-close { @@ -1059,6 +1091,7 @@ span.popup-close {
justify-content: space-between; */
display: flex;
margin-bottom: 2rem;
align-items: center;
}
.popup-avatar {
@ -1075,11 +1108,16 @@ span.popup-close { @@ -1075,11 +1108,16 @@ span.popup-close {
}
}
.popup-close {
font-size: 1.5rem;
}
h6 {
font-size: 1.1rem;
text-align: left;
margin: 0;
margin-left: 1.5rem;
font-weight: 400;
}
.crop {

1
webpack.dev.js

@ -6,5 +6,6 @@ module.exports = merge(common, { @@ -6,5 +6,6 @@ module.exports = merge(common, {
devtool: 'inline-source-map',
devServer: {
contentBase: './public',
http2: true
},
});

2
webpack.prod.js

@ -59,6 +59,8 @@ module.exports = merge(common, { @@ -59,6 +59,8 @@ module.exports = merge(common, {
files.forEach(file => {
//console.log('to unlink 1:', file);
if(file.includes('mitm.') || file.includes('sw.js')) return;
let p = path.resolve(buildDir + file);
if(!newlyCreatedAssets[file] && ['.gz', '.js'].find(ext => file.endsWith(ext)) !== undefined) {

Loading…
Cancel
Save