Browse Source

scroll try #10

master
Eduard Kuzmenko 4 years ago
parent
commit
c86671ce12
  1. BIN
      .DS_Store
  2. 213
      package-lock.json
  3. 4
      package.json
  4. 30
      src/components/misc.ts
  5. 353
      src/components/scrollable.ts
  6. 61
      src/components/wrappers.ts
  7. 1311
      src/lib/appManagers/appImManager.ts
  8. 7
      src/lib/appManagers/appSidebarLeft.ts
  9. 391
      src/lib/appManagers/appSidebarRight.ts
  10. 12
      src/lib/ckin.js
  11. 4
      src/lib/lottieLoader.ts
  12. 22
      src/lib/polyfill.ts
  13. 2
      src/lib/utils.js
  14. 40
      src/scss/partials/_chat.scss
  15. 286
      src/scss/partials/_rightSIdebar.scss
  16. 231
      src/scss/partials/_sidebar.scss
  17. 34
      src/scss/style.scss
  18. 4
      tsconfig.json
  19. 2
      webpack.prod.js

BIN
.DS_Store vendored

Binary file not shown.

213
package-lock.json generated

@ -4926,13 +4926,13 @@
} }
}, },
"globule": { "globule": {
"version": "1.2.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz",
"integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==",
"dev": true, "dev": true,
"requires": { "requires": {
"glob": "~7.1.1", "glob": "~7.1.1",
"lodash": "~4.17.10", "lodash": "~4.17.12",
"minimatch": "~3.0.2" "minimatch": "~3.0.2"
} }
}, },
@ -5555,13 +5555,10 @@
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
}, },
"is-finite": { "is-finite": {
"version": "1.0.2", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
"integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
"dev": true, "dev": true
"requires": {
"number-is-nan": "^1.0.0"
}
}, },
"is-fullwidth-code-point": { "is-fullwidth-code-point": {
"version": "2.0.0", "version": "2.0.0",
@ -6247,9 +6244,9 @@
} }
}, },
"js-base64": { "js-base64": {
"version": "2.5.1", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz",
"integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==", "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ==",
"dev": true "dev": true
}, },
"js-sha3": { "js-sha3": {
@ -7088,9 +7085,9 @@
} }
}, },
"node-sass": { "node-sass": {
"version": "4.13.0", "version": "4.13.1",
"resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.0.tgz", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz",
"integrity": "sha512-W1XBrvoJ1dy7VsvTAS5q1V45lREbTlZQqFbiHb3R3OTTCma0XBtuG6xZ6Z4506nR4lmHPTqVRwxT6KgtWC97CA==", "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==",
"dev": true, "dev": true,
"requires": { "requires": {
"async-foreach": "^0.1.3", "async-foreach": "^0.1.3",
@ -7191,9 +7188,9 @@
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
}, },
"npm": { "npm": {
"version": "6.13.4", "version": "6.14.1",
"resolved": "https://registry.npmjs.org/npm/-/npm-6.13.4.tgz", "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.1.tgz",
"integrity": "sha512-vTcUL4SCg3AzwInWTbqg1OIaOXlzKSS8Mb8kc5avwrJpcvevDA5J9BhYSuei+fNs3pwOp4lzA5x2FVDXACvoXA==", "integrity": "sha512-2hi3UF7g5VL8VKm46Bx5GAW28DPb8BJZbj2uONMBMhY8XkJ56lSmHJNFcjTQr7KHZqWqiBT5BugaQEy+Y/4T2g==",
"dev": true, "dev": true,
"requires": { "requires": {
"JSONStream": "^1.3.5", "JSONStream": "^1.3.5",
@ -7202,12 +7199,12 @@
"ansistyles": "~0.1.3", "ansistyles": "~0.1.3",
"aproba": "^2.0.0", "aproba": "^2.0.0",
"archy": "~1.0.0", "archy": "~1.0.0",
"bin-links": "^1.1.6", "bin-links": "^1.1.7",
"bluebird": "^3.5.5", "bluebird": "^3.5.5",
"byte-size": "^5.0.1", "byte-size": "^5.0.1",
"cacache": "^12.0.3", "cacache": "^12.0.3",
"call-limit": "^1.1.1", "call-limit": "^1.1.1",
"chownr": "^1.1.3", "chownr": "^1.1.4",
"ci-info": "^2.0.0", "ci-info": "^2.0.0",
"cli-columns": "^3.1.2", "cli-columns": "^3.1.2",
"cli-table3": "^0.5.1", "cli-table3": "^0.5.1",
@ -7227,7 +7224,7 @@
"glob": "^7.1.4", "glob": "^7.1.4",
"graceful-fs": "^4.2.3", "graceful-fs": "^4.2.3",
"has-unicode": "~2.0.1", "has-unicode": "~2.0.1",
"hosted-git-info": "^2.8.5", "hosted-git-info": "^2.8.7",
"iferr": "^1.0.2", "iferr": "^1.0.2",
"imurmurhash": "*", "imurmurhash": "*",
"infer-owner": "^1.0.4", "infer-owner": "^1.0.4",
@ -7245,7 +7242,7 @@
"libnpmorg": "^1.0.1", "libnpmorg": "^1.0.1",
"libnpmsearch": "^2.0.2", "libnpmsearch": "^2.0.2",
"libnpmteam": "^1.0.2", "libnpmteam": "^1.0.2",
"libnpx": "^10.2.0", "libnpx": "^10.2.2",
"lock-verify": "^2.1.0", "lock-verify": "^2.1.0",
"lockfile": "^1.0.4", "lockfile": "^1.0.4",
"lodash._baseindexof": "*", "lodash._baseindexof": "*",
@ -7264,7 +7261,7 @@
"mississippi": "^3.0.0", "mississippi": "^3.0.0",
"mkdirp": "~0.5.1", "mkdirp": "~0.5.1",
"move-concurrently": "^1.0.1", "move-concurrently": "^1.0.1",
"node-gyp": "^5.0.5", "node-gyp": "^5.0.7",
"nopt": "~4.0.1", "nopt": "~4.0.1",
"normalize-package-data": "^2.5.0", "normalize-package-data": "^2.5.0",
"npm-audit-report": "^1.3.2", "npm-audit-report": "^1.3.2",
@ -7272,16 +7269,16 @@
"npm-install-checks": "^3.0.2", "npm-install-checks": "^3.0.2",
"npm-lifecycle": "^3.1.4", "npm-lifecycle": "^3.1.4",
"npm-package-arg": "^6.1.1", "npm-package-arg": "^6.1.1",
"npm-packlist": "^1.4.7", "npm-packlist": "^1.4.8",
"npm-pick-manifest": "^3.0.2", "npm-pick-manifest": "^3.0.2",
"npm-profile": "^4.0.2", "npm-profile": "^4.0.2",
"npm-registry-fetch": "^4.0.2", "npm-registry-fetch": "^4.0.3",
"npm-user-validate": "~1.0.0", "npm-user-validate": "~1.0.0",
"npmlog": "~4.1.2", "npmlog": "~4.1.2",
"once": "~1.4.0", "once": "~1.4.0",
"opener": "^1.5.1", "opener": "^1.5.1",
"osenv": "^0.1.5", "osenv": "^0.1.5",
"pacote": "^9.5.11", "pacote": "^9.5.12",
"path-is-inside": "~1.0.2", "path-is-inside": "~1.0.2",
"promise-inflight": "~1.0.1", "promise-inflight": "~1.0.1",
"qrcode-terminal": "^0.12.0", "qrcode-terminal": "^0.12.0",
@ -7292,7 +7289,7 @@
"read-installed": "~4.0.3", "read-installed": "~4.0.3",
"read-package-json": "^2.1.1", "read-package-json": "^2.1.1",
"read-package-tree": "^5.3.1", "read-package-tree": "^5.3.1",
"readable-stream": "^3.4.0", "readable-stream": "^3.6.0",
"readdir-scoped-modules": "^1.1.0", "readdir-scoped-modules": "^1.1.0",
"request": "^2.88.0", "request": "^2.88.0",
"retry": "^0.12.0", "retry": "^0.12.0",
@ -7484,7 +7481,7 @@
} }
}, },
"bin-links": { "bin-links": {
"version": "1.1.6", "version": "1.1.7",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
@ -7597,7 +7594,7 @@
} }
}, },
"chownr": { "chownr": {
"version": "1.1.3", "version": "1.1.4",
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
@ -8037,7 +8034,7 @@
} }
}, },
"env-paths": { "env-paths": {
"version": "1.0.0", "version": "2.2.0",
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
@ -8381,7 +8378,7 @@
} }
}, },
"get-caller-file": { "get-caller-file": {
"version": "1.0.2", "version": "1.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
@ -8490,7 +8487,7 @@
"dev": true "dev": true
}, },
"hosted-git-info": { "hosted-git-info": {
"version": "2.8.5", "version": "2.8.7",
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
@ -8606,7 +8603,7 @@
} }
}, },
"invert-kv": { "invert-kv": {
"version": "1.0.0", "version": "2.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
@ -8795,11 +8792,11 @@
"dev": true "dev": true
}, },
"lcid": { "lcid": {
"version": "1.0.0", "version": "2.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
"invert-kv": "^1.0.0" "invert-kv": "^2.0.0"
} }
}, },
"libcipm": { "libcipm": {
@ -8972,7 +8969,7 @@
} }
}, },
"libnpx": { "libnpx": {
"version": "10.2.0", "version": "10.2.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
@ -9123,17 +9120,34 @@
"ssri": "^6.0.0" "ssri": "^6.0.0"
} }
}, },
"map-age-cleaner": {
"version": "0.1.3",
"bundled": true,
"dev": true,
"requires": {
"p-defer": "^1.0.0"
}
},
"meant": { "meant": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
"mem": { "mem": {
"version": "1.1.0", "version": "4.3.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
"mimic-fn": "^1.0.0" "map-age-cleaner": "^0.1.1",
"mimic-fn": "^2.0.0",
"p-is-promise": "^2.0.0"
},
"dependencies": {
"mimic-fn": {
"version": "2.1.0",
"bundled": true,
"dev": true
}
} }
}, },
"mime-db": { "mime-db": {
@ -9149,11 +9163,6 @@
"mime-db": "~1.35.0" "mime-db": "~1.35.0"
} }
}, },
"mimic-fn": {
"version": "1.2.0",
"bundled": true,
"dev": true
},
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
@ -9241,6 +9250,11 @@
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
"nice-try": {
"version": "1.0.5",
"bundled": true,
"dev": true
},
"node-fetch-npm": { "node-fetch-npm": {
"version": "2.0.2", "version": "2.0.2",
"bundled": true, "bundled": true,
@ -9252,36 +9266,21 @@
} }
}, },
"node-gyp": { "node-gyp": {
"version": "5.0.5", "version": "5.0.7",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
"env-paths": "^1.0.0", "env-paths": "^2.2.0",
"glob": "^7.0.3", "glob": "^7.1.4",
"graceful-fs": "^4.1.2", "graceful-fs": "^4.2.2",
"mkdirp": "^0.5.0", "mkdirp": "^0.5.1",
"nopt": "2 || 3", "nopt": "^4.0.1",
"npmlog": "0 || 1 || 2 || 3 || 4", "npmlog": "^4.1.2",
"request": "^2.87.0", "request": "^2.88.0",
"rimraf": "2", "rimraf": "^2.6.3",
"semver": "~5.3.0", "semver": "^5.7.1",
"tar": "^4.4.12", "tar": "^4.4.12",
"which": "1" "which": "^1.3.1"
},
"dependencies": {
"nopt": {
"version": "3.0.6",
"bundled": true,
"dev": true,
"requires": {
"abbrev": "1"
}
},
"semver": {
"version": "5.3.0",
"bundled": true,
"dev": true
}
} }
}, },
"nopt": { "nopt": {
@ -9381,12 +9380,13 @@
} }
}, },
"npm-packlist": { "npm-packlist": {
"version": "1.4.7", "version": "1.4.8",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
"ignore-walk": "^3.0.1", "ignore-walk": "^3.0.1",
"npm-bundled": "^1.0.1" "npm-bundled": "^1.0.1",
"npm-normalize-package-bin": "^1.0.1"
} }
}, },
"npm-pick-manifest": { "npm-pick-manifest": {
@ -9410,7 +9410,7 @@
} }
}, },
"npm-registry-fetch": { "npm-registry-fetch": {
"version": "4.0.2", "version": "4.0.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
@ -9502,13 +9502,41 @@
"dev": true "dev": true
}, },
"os-locale": { "os-locale": {
"version": "2.1.0", "version": "3.1.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
"execa": "^0.7.0", "execa": "^1.0.0",
"lcid": "^1.0.0", "lcid": "^2.0.0",
"mem": "^1.1.0" "mem": "^4.0.0"
},
"dependencies": {
"cross-spawn": {
"version": "6.0.5",
"bundled": true,
"dev": true,
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"execa": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
}
} }
}, },
"os-tmpdir": { "os-tmpdir": {
@ -9525,11 +9553,21 @@
"os-tmpdir": "^1.0.0" "os-tmpdir": "^1.0.0"
} }
}, },
"p-defer": {
"version": "1.0.0",
"bundled": true,
"dev": true
},
"p-finally": { "p-finally": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
"p-is-promise": {
"version": "2.1.0",
"bundled": true,
"dev": true
},
"p-limit": { "p-limit": {
"version": "1.2.0", "version": "1.2.0",
"bundled": true, "bundled": true,
@ -9563,7 +9601,7 @@
} }
}, },
"pacote": { "pacote": {
"version": "9.5.11", "version": "9.5.12",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
@ -9877,7 +9915,7 @@
} }
}, },
"readable-stream": { "readable-stream": {
"version": "3.4.0", "version": "3.6.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
@ -10261,11 +10299,18 @@
} }
}, },
"string_decoder": { "string_decoder": {
"version": "1.2.0", "version": "1.3.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
"safe-buffer": "~5.1.0" "safe-buffer": "~5.2.0"
},
"dependencies": {
"safe-buffer": {
"version": "5.2.0",
"bundled": true,
"dev": true
}
} }
}, },
"stringify-package": { "stringify-package": {
@ -10646,7 +10691,7 @@
"dev": true "dev": true
}, },
"yargs": { "yargs": {
"version": "11.0.0", "version": "11.1.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
@ -10654,7 +10699,7 @@
"decamelize": "^1.1.1", "decamelize": "^1.1.1",
"find-up": "^2.1.0", "find-up": "^2.1.0",
"get-caller-file": "^1.0.1", "get-caller-file": "^1.0.1",
"os-locale": "^2.0.0", "os-locale": "^3.1.0",
"require-directory": "^2.1.1", "require-directory": "^2.1.1",
"require-main-filename": "^1.0.1", "require-main-filename": "^1.0.1",
"set-blocking": "^2.0.0", "set-blocking": "^2.0.0",

4
package.json

@ -42,8 +42,8 @@
"jest": "^24.9.0", "jest": "^24.9.0",
"leemon": "^6.2.0", "leemon": "^6.2.0",
"lottie-web": "^5.6.4", "lottie-web": "^5.6.4",
"node-sass": "^4.13.0", "node-sass": "^4.13.1",
"npm": "^6.13.4", "npm": "^6.14.1",
"offscreen-canvas": "^0.1.1", "offscreen-canvas": "^0.1.1",
"on-build-webpack": "^0.1.0", "on-build-webpack": "^0.1.0",
"overlayscrollbars": "^1.10.0", "overlayscrollbars": "^1.10.0",

30
src/components/misc.ts

@ -52,11 +52,23 @@ export function ripple(elem: Element) {
} }
} }
export function putPreloader(elem: Element) { export function putPreloader(elem: Element, returnDiv = false) {
const html = ` const html = `
<svg xmlns="http://www.w3.org/2000/svg" class="preloader-circular" viewBox="25 25 50 50"> <svg xmlns="http://www.w3.org/2000/svg" class="preloader-circular" viewBox="25 25 50 50">
<circle class="preloader-path" cx="50" cy="50" r="20" fill="none" stroke-miterlimit="10"/> <circle class="preloader-path" cx="50" cy="50" r="20" fill="none" stroke-miterlimit="10"/>
</svg>`; </svg>`;
if(returnDiv) {
let div = document.createElement('div');
div.classList.add('preloader');
div.innerHTML = html;
if(elem) {
elem.appendChild(div);
}
return div;
}
elem.innerHTML += html; elem.innerHTML += html;
} }
@ -76,18 +88,19 @@ export function horizontalMenu(tabs: HTMLUListElement, content: HTMLDivElement,
///////console.log('tabs click:', target); ///////console.log('tabs click:', target);
if(!target || target.classList.contains('active')) return false; if(!target) return false;
let id = whichChild(target);
let tabContent = content.children[id] as HTMLDivElement;
if(onClick) onClick(id, tabContent);
if(target.classList.contains('active') || id == prevId) {
return false;
}
let prev = tabs.querySelector('li.active') as HTMLLIElement; let prev = tabs.querySelector('li.active') as HTMLLIElement;
prev && prev.classList.remove('active'); prev && prev.classList.remove('active');
target.classList.add('active'); target.classList.add('active');
let id = whichChild(target);
if(id == prevId) return false;
let tabContent = content.children[id] as HTMLDivElement;
tabContent.classList.add('active'); tabContent.classList.add('active');
/////console.log('mambo rap', prevId, id); /////console.log('mambo rap', prevId, id);
@ -139,7 +152,6 @@ export function horizontalMenu(tabs: HTMLUListElement, content: HTMLDivElement,
if(onTransitionEnd) onTransitionEnd(); if(onTransitionEnd) onTransitionEnd();
}, 200); }, 200);
if(onClick) onClick(id, tabContent);
prevTabContent = tabContent; prevTabContent = tabContent;
}); });
} }

353
src/components/scrollable.ts

@ -32,12 +32,13 @@ export default class Scrollable {
public type: string; public type: string;
public side: string; public side: string;
public translate: string;
public scrollType: string; public scrollType: string;
public scrollSide: string; public scrollSide: string;
public clientAxis: string; public clientAxis: string;
public scrollSize = -1; public scrollSize = -1; // it will be scrollHeight
public size = 0; public size = 0; // it will be outerHeight of container (not scrollHeight)
public thumbSize = 0; public thumbSize = 0;
public hiddenElements: { public hiddenElements: {
@ -57,11 +58,12 @@ export default class Scrollable {
public onAddedBottom: () => void = null; public onAddedBottom: () => void = null;
public onScrolledTop: () => void = null; public onScrolledTop: () => void = null;
public onScrolledBottom: () => void = null; public onScrolledBottom: () => void = null;
public onScrolledTopFired = false;
public onScrolledBottomFired = false;
public topObserver: IntersectionObserver; public topObserver: IntersectionObserver;
public bottomObserver: IntersectionObserver; public bottomObserver: IntersectionObserver;
public splitObserver: IntersectionObserver;
public splitMeasureTop: Promise<{element: Element, height: number}[]> = null; public splitMeasureTop: Promise<{element: Element, height: number}[]> = null;
public splitMeasureBottom: Scrollable['splitMeasureTop'] = null; public splitMeasureBottom: Scrollable['splitMeasureTop'] = null;
public splitMeasureAdd: Promise<number> = null; public splitMeasureAdd: Promise<number> = null;
@ -86,37 +88,17 @@ export default class Scrollable {
private log: ReturnType<typeof logger>; private log: ReturnType<typeof logger>;
private debug = false; private debug = false;
constructor(public el: HTMLDivElement, x = false, y = true, public splitOffset = 300, logPrefix = '') { constructor(public el: HTMLDivElement, x = false, y = true, public splitOffset = 300, logPrefix = '', public appendTo = el, public onScrollOffset = splitOffset) {
this.container = document.createElement('div'); this.container = document.createElement('div');
this.container.classList.add('scrollable'); this.container.classList.add('scrollable');
this.log = logger('SCROLL' + (logPrefix ? '-' + logPrefix : '')); this.log = logger('SCROLL' + (logPrefix ? '-' + logPrefix : ''));
let arr = [];
for(let i = 0.001; i < 1; i += 0.001) arr.push(i);
this.topObserver = new IntersectionObserver(entries => {
let entry = entries[entries.length - 1];
//console.log('top intersection:', entries, entry.isIntersecting, entry.intersectionRatio > 0);
if(entry.isIntersecting) {
if(this.onScrolledTop) this.onScrolledTop();
}
// console.log('top intersection end');
}, {root: this.el});
this.bottomObserver = new IntersectionObserver(entries => {
let entry = entries[entries.length - 1];
//console.log('bottom intersection:', entries, entry, entry.isIntersecting, entry.intersectionRatio > 0);
if(entry.isIntersecting) {
if(this.onScrolledBottom) this.onScrolledBottom();
}
}, {root: this.el});
if(x) { if(x) {
this.container.classList.add('scrollable-x'); this.container.classList.add('scrollable-x');
this.type = 'width'; this.type = 'width';
this.side = 'left'; this.side = 'left';
this.translate = 'translateX';
this.scrollType = 'scrollWidth'; this.scrollType = 'scrollWidth';
this.scrollSide = 'scrollLeft'; this.scrollSide = 'scrollLeft';
this.clientAxis = 'clientX'; this.clientAxis = 'clientX';
@ -141,6 +123,7 @@ export default class Scrollable {
this.container.classList.add('scrollable-y'); this.container.classList.add('scrollable-y');
this.type = 'height'; this.type = 'height';
this.side = 'top'; this.side = 'top';
this.translate = 'translateY';
this.scrollType = 'scrollHeight'; this.scrollType = 'scrollHeight';
this.scrollSide = 'scrollTop'; this.scrollSide = 'scrollTop';
this.clientAxis = 'clientY'; this.clientAxis = 'clientY';
@ -181,16 +164,14 @@ export default class Scrollable {
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
//this.resize.bind(this); //this.resize.bind(this);
this.onScroll(); this.onScroll();
this.resize();
}); });
this.paddingTopDiv = document.createElement('div'); this.paddingTopDiv = document.createElement('div');
this.paddingTopDiv.classList.add('scroll-padding'); this.paddingTopDiv.classList.add('scroll-padding');
this.paddingBottomDiv = document.createElement('div'); this.paddingBottomDiv = document.createElement('div');
this.paddingBottomDiv.classList.add('scroll-padding'); this.paddingBottomDiv.classList.add('scroll-padding');
this.topObserver.observe(this.paddingTopDiv);
this.bottomObserver.observe(this.paddingBottomDiv);
this.container.addEventListener('scroll', this.onScroll.bind(this)); this.container.addEventListener('scroll', this.onScroll.bind(this));
Array.from(el.children).forEach(c => this.container.append(c)); Array.from(el.children).forEach(c => this.container.append(c));
@ -280,181 +261,9 @@ export default class Scrollable {
}); });
} }
public detachByPrevScroll(child: Element, prevScrollTop: number, needHeight = 0) { public resize() {
if(this.splitMeasureBottom) fastdom.clear(this.splitMeasureBottom);
if(this.splitMutateBottom) fastdom.clear(this.splitMutateBottom);
let attachToTop = this.paddings.up < prevScrollTop;
this.splitMeasureBottom = fastdom.measure(() => {
let sliced: {element: Element, height: number}[] = [];
do {
if(needHeight > 0) {
needHeight -= child.scrollHeight;
} else {
sliced.push({element: child, height: child.scrollHeight});
}
} while(child = child.nextElementSibling);
return sliced;
});
return this.splitMeasureBottom.then(sliced => {
if(this.splitMutateBottom) fastdom.clear(this.splitMutateBottom);
return this.splitMutateBottom = fastdom.mutate(() => {
sliced.forEachReverse((child) => {
let {element, height} = child;
if(!this.splitUp.contains(element)) return;
this.paddings.down += height;
this.hiddenElements.down.unshift(child);
this.splitUp.removeChild(element);
//element.parentElement.removeChild(element);
});
this.log('sliced down', sliced);
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
});
});
}
public splitObserve(entries: IntersectionObserverEntry[]) {
let sorted: {
intersecting: {
top?: IntersectionObserverEntry,
bottom?: IntersectionObserverEntry
},
notIntersecting: {
top?: IntersectionObserverEntry,
bottom?: IntersectionObserverEntry
}
} = {
intersecting: {},
notIntersecting: {}
};
for(let entry of entries) { // there may be duplicates (1st - not intersecting, 2nd - intersecting)
//console.log('onscroll entry 1', entry.target, entry.isIntersecting, entry);
if(!entry.target.parentElement || !entry.rootBounds) continue;
if(!entry.isIntersecting) {
let isTop = entry.boundingClientRect.top <= 0;
let isBottom = entry.rootBounds.height <= entry.boundingClientRect.top;
//console.log('onscroll entry notIntersecting', isTop, isBottom, entry.target, entry);
if(isTop) {
sorted.notIntersecting.top = entry;
} else if(isBottom && !sorted.notIntersecting.bottom) {
sorted.notIntersecting.bottom = entry;
}
//console.log('splitObserver', entry, entry.target, isTop);
} else {
let isTop = entry.boundingClientRect.top <= entry.rootBounds.top;
let isBottom = entry.boundingClientRect.bottom >= entry.rootBounds.bottom;
if(isTop) {
sorted.intersecting.top = entry;
} else if(isBottom && !sorted.intersecting.bottom) {
sorted.intersecting.bottom = entry;
}
// if(isTop) {
// this.onTopIntersection(entry.boundingClientRect.height);
// } else if(isBottom) {
// this.onTopIntersection(entry.boundingClientRect.height);
// }
}
}
console.log('splitObserve', entries, sorted);
let needHeight = this.splitOffset;
let isOutOfView: boolean;
let entry: IntersectionObserverEntry;
if(entry = sorted.notIntersecting.top) { // scrolled bottom
let child = entry.target;
let diff = entry.boundingClientRect.bottom + needHeight;
if(diff < 0) { // maybe need <=, means out of view
if(!(child = child.nextElementSibling)) {
this.detachTop(this.splitUp.lastElementChild, 0);
} else {
if(this.splitMeasureRemoveBad) fastdom.clear(this.splitMeasureRemoveBad);
this.splitMeasureRemoveBad = fastdom.measure(() => {
do {
diff += child.scrollHeight;
} while(diff < 0 && (child = child.nextElementSibling));
return child || this.splitUp.lastElementChild;
});
this.splitMeasureRemoveBad.then(child => {
this.detachTop(child, 0);
});
}
} else {
this.detachTop(child, needHeight);
}
}
if(entry = sorted.notIntersecting.bottom) { // scrolled top
isOutOfView = (entry.boundingClientRect.top - needHeight) >= entry.rootBounds.height;
this.detachBottom(entry.target, isOutOfView ? 0 : needHeight);
}
if(entry = sorted.intersecting.top) { // scrolling top
let needHeight = this.splitOffset;
let child = entry.target;
if(this.splitMeasureAdd) fastdom.clear(this.splitMeasureAdd);
this.splitMeasureAdd = fastdom.measure(() => {
while(child = child.previousElementSibling) {
needHeight -= child.scrollHeight;
}
return needHeight;
});
this.splitMeasureAdd.then(needHeight => {
this.onTopIntersection(needHeight);
});
}
if(entry = sorted.intersecting.bottom) { // scrolling bottom
let needHeight = this.splitOffset;
let child = entry.target;
if(this.splitMeasureAdd) fastdom.clear(this.splitMeasureAdd);
this.splitMeasureAdd = fastdom.measure(() => {
while(child = child.nextElementSibling) {
needHeight -= child.scrollHeight;
}
return needHeight;
});
this.splitMeasureAdd.then(needHeight => {
this.onBottomIntersection(needHeight);
});
}
}
public async resize() {
//console.time('scroll resize'); //console.time('scroll resize');
fastdom.mutate(() => {
await fastdom.measure(() => {
// @ts-ignore
this.scrollSize = this.container[this.scrollType];
let rect = this.container.getBoundingClientRect();
// @ts-ignore
this.size = rect[this.type];
});
await fastdom.mutate(() => {
if(!this.size || this.size == this.scrollSize) { if(!this.size || this.size == this.scrollSize) {
this.thumbSize = 0; this.thumbSize = 0;
@ -480,7 +289,7 @@ export default class Scrollable {
//console.log('onresize', thumb.style[type], thumbHeight, height); //console.log('onresize', thumb.style[type], thumbHeight, height);
} }
public async setVirtualContainer(el?: HTMLElement) { public setVirtualContainer(el?: HTMLElement) {
this.splitUp = el; this.splitUp = el;
this.hiddenElements.up.length = this.hiddenElements.down.length = 0; this.hiddenElements.up.length = this.hiddenElements.down.length = 0;
@ -494,12 +303,6 @@ export default class Scrollable {
}); });
} }
/* if(this.splitObserver) {
this.splitObserver.disconnect();
}
this.splitObserver = new IntersectionObserver((entries) => this.splitObserve(entries), {root: this.el}); */
this.log('setVirtualContainer:', el, this); this.log('setVirtualContainer:', el, this);
this.getScrollTopOffset(); this.getScrollTopOffset();
@ -509,6 +312,9 @@ export default class Scrollable {
el.parentElement.insertBefore(this.paddingTopDiv, el); el.parentElement.insertBefore(this.paddingTopDiv, el);
el.parentNode.insertBefore(this.paddingBottomDiv, el.nextSibling); el.parentNode.insertBefore(this.paddingBottomDiv, el.nextSibling);
}); });
} else {
this.paddingTopDiv.remove();
this.paddingBottomDiv.remove();
} }
} }
@ -529,33 +335,66 @@ export default class Scrollable {
public onScroll() { public onScroll() {
if(this.onScrollMeasure) fastdom.clear(this.onScrollMeasure); if(this.onScrollMeasure) fastdom.clear(this.onScrollMeasure);
this.onScrollMeasure = fastdom.measure(() => { this.onScrollMeasure = fastdom.measure(() => {
// @ts-ignore quick brown fix
this.size = this.parentElement[this.scrollType];
// @ts-ignore // @ts-ignore
if(this.container[this.scrollType] != this.scrollSize || this.thumbSize == 0) { let scrollSize = this.container[this.scrollType];
if(scrollSize != this.scrollSize || this.thumbSize == 0) {
this.resize(); this.resize();
} }
this.scrollSize = scrollSize;
// @ts-ignore // @ts-ignore
let value = this.container[this.scrollSide] / (this.scrollSize - this.size) * 100; let scrollPos = this.container[this.scrollSide];
let maxValue = 100 - (this.thumbSize / this.size * 100);
// let value = scrollPos / (this.scrollSize - this.size) * 100;
// let maxValue = 100 - (this.thumbSize / this.size * 100);
let value = scrollPos / (this.scrollSize - this.size) * this.size;
let maxValue = this.size - this.thumbSize;
//this.log(scrollPos, this.scrollSize, this.size, value, scrollPos / (this.scrollSize - this.size) * this.size);
let ret = {value, maxValue}; let ret = {value, maxValue};
let scrollTop = scrollPos - this.scrollTopOffset;
let maxScrollTop = this.scrollSize - this.scrollTopOffset - this.size;
if(this.onScrolledBottom) {
if(!this.hiddenElements.down.length && (maxScrollTop - scrollTop) <= this.onScrollOffset) {
if(!this.onScrolledBottomFired) {
this.onScrolledBottomFired = true;
this.onScrolledBottom();
}
} else {
this.onScrolledBottomFired = false;
}
}
if(this.onScrolledTop) {
//this.log('onScrolledTop:', scrollTop, this.onScrollOffset);
if(!this.hiddenElements.up.length && scrollTop <= this.onScrollOffset) {
if(!this.onScrolledTopFired) {
this.onScrolledTopFired = true;
this.onScrolledTop();
}
} else {
this.onScrolledTopFired = false;
}
}
if(!this.splitUp) { if(!this.splitUp) {
return ret; return ret;
} }
let perf = performance.now(); let perf = performance.now();
let scrollTop = this.scrollTop - this.scrollTopOffset;
let outerHeight = this.parentElement.scrollHeight;
let maxScrollTop = this.scrollHeight - this.scrollTopOffset - outerHeight;
if(scrollTop < 0) scrollTop = 0; if(scrollTop < 0) scrollTop = 0;
else if(scrollTop > maxScrollTop) scrollTop = maxScrollTop; else if(scrollTop > maxScrollTop) scrollTop = maxScrollTop;
let toBottom = scrollTop > this.lastScrollTop; let toBottom = scrollTop > this.lastScrollTop;
let visibleFrom = /* scrollTop < this.paddings.up ? scrollTop : */scrollTop - this.paddings.up; let visibleFrom = /* scrollTop < this.paddings.up ? scrollTop : */scrollTop - this.paddings.up;
let visibleUntil = visibleFrom + outerHeight; let visibleUntil = visibleFrom + this.size;
let sum = 0; let sum = 0;
let firstVisibleElement: Element; let firstVisibleElement: Element;
@ -619,10 +458,6 @@ export default class Scrollable {
this.onBottomIntersection(needHeight); this.onBottomIntersection(needHeight);
return needHeight; return needHeight;
}); });
/* this.splitMeasureAdd.then(needHeight => {
this.onBottomIntersection(needHeight);
}); */
} else if(length) { // scrolled manually or safari } else if(length) { // scrolled manually or safari
if(this.debug) { if(this.debug) {
this.log.warn('will detach all of top', length, this.splitUp.childElementCount, maxScrollTop, this.paddings, this.lastScrollTop); this.log.warn('will detach all of top', length, this.splitUp.childElementCount, maxScrollTop, this.paddings, this.lastScrollTop);
@ -652,10 +487,6 @@ export default class Scrollable {
this.onTopIntersection(needHeight); this.onTopIntersection(needHeight);
return needHeight; return needHeight;
}); });
/* this.splitMeasureAdd.then(needHeight => {
this.onTopIntersection(needHeight);
}); */
} else if(length) { // scrolled manually or safari } else if(length) { // scrolled manually or safari
if(this.debug) { if(this.debug) {
this.log.warn('will detach all of bottom', length, this.splitUp.childElementCount, maxScrollTop, this.paddings, this.lastScrollTop); this.log.warn('will detach all of bottom', length, this.splitUp.childElementCount, maxScrollTop, this.paddings, this.lastScrollTop);
@ -681,7 +512,8 @@ export default class Scrollable {
this.onScrollMeasure.then(({value, maxValue}) => { this.onScrollMeasure.then(({value, maxValue}) => {
fastdom.mutate(() => { fastdom.mutate(() => {
// @ts-ignore // @ts-ignore
this.thumb.style[this.side] = (value >= maxValue ? maxValue : value) + '%'; //this.thumb.style[this.side] = (value >= maxValue ? maxValue : value) + '%';
this.thumb.style.transform = this.translate + '(' + (value >= maxValue ? maxValue : value) + 'px)';
}); });
}); });
@ -691,7 +523,7 @@ export default class Scrollable {
public onManualScrollTop(scrollTop: number, needHeight: number, maxScrollTop: number) { public onManualScrollTop(scrollTop: number, needHeight: number, maxScrollTop: number) {
//if(this.splitMutateRemoveBad) fastdom.clear(this.splitMutateRemoveBad); //if(this.splitMutateRemoveBad) fastdom.clear(this.splitMutateRemoveBad);
this.splitMutateRemoveBad = fastdom.mutate(() => { this.splitMutateRemoveBad = fastdom.mutate(() => {
let h = maxScrollTop - (scrollTop + outerHeight); let h = maxScrollTop - (scrollTop + this.size);
while(this.paddings.down < h && this.paddings.up) { while(this.paddings.down < h && this.paddings.up) {
let child = this.hiddenElements.up.pop(); let child = this.hiddenElements.up.pop();
@ -705,11 +537,8 @@ export default class Scrollable {
} }
this.paddingBottomDiv.style.height = this.paddings.down + 'px'; this.paddingBottomDiv.style.height = this.paddings.down + 'px';
this.onTopIntersection((outerHeight * 2) + (needHeight * 2)); this.onTopIntersection((this.size * 2) + (needHeight * 2));
}); });
/* this.splitMutateRemoveBad.then(() => {
}); */
} }
public onManualScrollBottom(scrollTop: number, needHeight: number) { public onManualScrollBottom(scrollTop: number, needHeight: number) {
@ -729,11 +558,8 @@ export default class Scrollable {
} }
this.paddingTopDiv.style.height = this.paddings.up + 'px'; this.paddingTopDiv.style.height = this.paddings.up + 'px';
this.onBottomIntersection(outerHeight + (needHeight * 2)); this.onBottomIntersection(this.size + (needHeight * 2));
}); });
/* this.splitMutateRemoveBad.then(() => {
}); */
} }
public onTopIntersection(needHeight: number) { public onTopIntersection(needHeight: number) {
@ -813,7 +639,7 @@ export default class Scrollable {
}); });
if(this.hiddenElements.up.length) { if(this.hiddenElements.up.length) {
fastdom.mutate(() => { /* fastdom.mutate(() => {
this.splitUp.append(...smth); this.splitUp.append(...smth);
}).then(() => { }).then(() => {
return fastdom.measure(() => { return fastdom.measure(() => {
@ -839,13 +665,26 @@ export default class Scrollable {
this.onScroll(); this.onScroll();
}); });
}); */
this.splitUp.prepend(...smth);
smth.forEachReverse(node => {
let height = node.scrollHeight;
this.log('will append element to up hidden', node, height);
this.paddings.up += height;
this.hiddenElements.up.unshift({
element: node,
height: height
});
node.parentElement.removeChild(node);
}); });
this.paddingTopDiv.style.height = this.paddings.up + 'px';
this.onScroll();
} else { } else {
this.splitUp.prepend(...smth); this.splitUp.prepend(...smth);
this.onScroll(); this.onScroll();
} }
} else { } else {
this.container.prepend(...smth); this.appendTo.prepend(...smth);
this.onScroll(); this.onScroll();
} }
@ -891,7 +730,7 @@ export default class Scrollable {
this.onScroll(); this.onScroll();
} }
} else { } else {
this.container.append(...smth); this.appendTo.append(...smth);
this.onScroll(); this.onScroll();
} }
@ -914,17 +753,14 @@ export default class Scrollable {
} }
} }
let index = this.hiddenElements.up.findIndex(c => c.element == element); let child = this.hiddenElements.up.findAndSplice(c => c.element == element);
let child: {element: Element, height: number};
let foundUp = false; let foundUp = false;
if(index !== -1) { if(child) {
child = this.hiddenElements.up.splice(index, 1)[0];
this.paddings.up -= child.height; this.paddings.up -= child.height;
foundUp = true; foundUp = true;
} else { } else {
index = this.hiddenElements.down.findIndex(c => c.element == element); child = this.hiddenElements.down.findAndSplice(c => c.element == element);
if(index !== -1) { if(child) {
child = this.hiddenElements.down.splice(index, 1)[0];
this.paddings.down -= child.height; this.paddings.down -= child.height;
} }
} }
@ -943,7 +779,7 @@ export default class Scrollable {
} }
public insertBefore(newChild: Element, refChild: Element, height?: number) { public insertBefore(newChild: Element, refChild: Element, height?: number) {
this.log('insertBefore', newChild, refChild); //this.log('insertBefore', newChild, refChild);
return; return;
if(this.splitUp) { if(this.splitUp) {
@ -1022,6 +858,29 @@ export default class Scrollable {
this.onScroll(); this.onScroll();
return ret; return ret;
} }
public scrollIntoView(element: Element) {
if(element.parentElement) {
element.scrollIntoView();
} else if(this.splitUp) {
let index = this.hiddenElements.up.findIndex(e => e.element == element);
let y = 0;
if(index !== -1) {
for(let i = 0; i < index; ++i) {
y += this.hiddenElements.up[i].height;
}
this.scrollTop = y;
} else if((index = this.hiddenElements.down.findIndex(e => e.element == element)) !== -1) {
y += this.paddings.up + this.size;
for(let i = 0; i < index; ++i) {
y += this.hiddenElements.down[i].height;
}
this.scrollTop = y;
}
}
}
set scrollTop(y: number) { set scrollTop(y: number) {
fastdom.mutate(() => { fastdom.mutate(() => {

61
src/components/wrappers.ts

@ -259,15 +259,21 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.classList.add('audio-waveform'); svg.classList.add('audio-waveform');
svg.setAttributeNS(null, 'width', '250'); svg.setAttributeNS(null, 'width', '190');
svg.setAttributeNS(null, 'height', '23'); svg.setAttributeNS(null, 'height', '23');
svg.setAttributeNS(null, 'viewBox', '0 0 250 23'); svg.setAttributeNS(null, 'viewBox', '0 0 190 23');
div.insertBefore(svg, div.lastElementChild); div.insertBefore(svg, div.lastElementChild);
let wave = doc.attributes[0].waveform as Uint8Array; let wave = doc.attributes[0].waveform as Uint8Array;
let index = 0; let index = 0;
let skipped = 0;
for(let uint8 of wave) { for(let uint8 of wave) {
if (index > 0 && index % 4 == 0) {
++index;
++skipped;
continue;
}
let percents = uint8 / 255; let percents = uint8 / 255;
let height = 23 * percents; let height = 23 * percents;
@ -276,12 +282,14 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
} }
svg.insertAdjacentHTML('beforeend', ` svg.insertAdjacentHTML('beforeend', `
<rect x="${index * 4}" y="${23 - height}" width="2" height="${height}" rx="1" ry="1"></rect> <rect x="${(index - skipped) * 4}" y="${23 - height}" width="2" height="${height}" rx="1" ry="1"></rect>
`); `);
++index; ++index;
} }
let progress = div.querySelector('.audio-waveform') as HTMLDivElement;
let onClick = () => { let onClick = () => {
if(!promise) { if(!promise) {
if(downloadDiv.classList.contains('downloading')) { if(downloadDiv.classList.contains('downloading')) {
@ -310,6 +318,7 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
let toggle = div.querySelector('.audio-toggle') as HTMLDivElement; let toggle = div.querySelector('.audio-toggle') as HTMLDivElement;
let interval = 0; let interval = 0;
let lastIndex = 0;
toggle.addEventListener('click', () => { toggle.addEventListener('click', () => {
if(audio.paused) { if(audio.paused) {
@ -327,7 +336,6 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
(Array.from(svg.children) as HTMLElement[]).forEach(node => node.classList.remove('active')); (Array.from(svg.children) as HTMLElement[]).forEach(node => node.classList.remove('active'));
let lastIndex = 0;
interval = setInterval(() => { interval = setInterval(() => {
if(lastIndex > svg.childElementCount || isNaN(audio.duration)) { if(lastIndex > svg.childElementCount || isNaN(audio.duration)) {
clearInterval(interval); clearInterval(interval);
@ -337,10 +345,11 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
// @ts-ignore // @ts-ignore
timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true); timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true);
lastIndex = Math.round(audio.currentTime / audio.duration * 62); lastIndex = Math.round(audio.currentTime / audio.duration * 47);
//svg.children[lastIndex].setAttributeNS(null, 'fill', '#000'); //svg.children[lastIndex].setAttributeNS(null, 'fill', '#000');
svg.children[lastIndex].classList.add('active'); //svg.children[lastIndex].classList.add('active'); #Иногда пропускает полоски..
(Array.from(svg.children) as HTMLElement[]).slice(0,lastIndex+1).forEach(node => node.classList.add('active'));
//++lastIndex; //++lastIndex;
//console.log('lastIndex:', lastIndex, audio.currentTime); //console.log('lastIndex:', lastIndex, audio.currentTime);
//}, duration * 1000 / svg.childElementCount | 0/* 63 * duration / 10 */); //}, duration * 1000 / svg.childElementCount | 0/* 63 * duration / 10 */);
@ -358,11 +367,51 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
toggle.classList.add('tgico-largeplay'); toggle.classList.add('tgico-largeplay');
toggle.classList.remove('tgico-largepause'); toggle.classList.remove('tgico-largepause');
clearInterval(interval); clearInterval(interval);
(Array.from(svg.children) as HTMLElement[]).forEach(node => node.classList.remove('active'));
// @ts-ignore // @ts-ignore
timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true); timeDiv.innerText = String(audio.currentTime | 0).toHHMMSS(true);
}); });
let mousedown = false, mousemove = false;
progress.addEventListener('mouseleave', (e) => {
if(mousedown) {
audio.play();
mousedown = false;
}
mousemove = false;
})
progress.addEventListener('mousemove', (e) => {
mousemove = true;
if(mousedown) scrub(e, audio, progress);
});
progress.addEventListener('mousedown', (e) => {
e.preventDefault();
if(!audio.paused) {
audio.pause();
scrub(e, audio, progress);
mousedown = true;
}
});
progress.addEventListener('mouseup', (e) => {
if (mousemove && mousedown) {
audio.play();
mousedown = false;
}
});
progress.addEventListener('click', (e) => {
if(!audio.paused) scrub(e, audio, progress);
});
function scrub(e: MouseEvent, audio: HTMLAudioElement, progress: HTMLDivElement) {
let scrubTime = e.offsetX / 190 /* width */ * audio.duration;
(Array.from(svg.children) as HTMLElement[]).forEach(node => node.classList.remove('active'));
lastIndex = Math.round(scrubTime / audio.duration * 47);
(Array.from(svg.children) as HTMLElement[]).slice(0,lastIndex+1).forEach(node => node.classList.add('active'));
audio.currentTime = scrubTime;
}
audio.append(source); audio.append(source);
audio.style.display = 'none'; audio.style.display = 'none';
div.append(audio); div.append(audio);

1311
src/lib/appManagers/appImManager.ts

File diff suppressed because it is too large Load Diff

7
src/lib/appManagers/appSidebarLeft.ts

@ -87,9 +87,7 @@ class AppSidebarLeft {
}; };
constructor() { constructor() {
this.chatsPreloader = document.createElement('div'); this.chatsPreloader = putPreloader(null, true);
this.chatsPreloader.classList.add('preloader');
putPreloader(this.chatsPreloader);
//this.chatsContainer.append(this.chatsPreloader); //this.chatsContainer.append(this.chatsPreloader);
//this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5); //this.chatsLoadCount = Math.round(document.body.scrollHeight / 70 * 1.5);
@ -98,7 +96,6 @@ class AppSidebarLeft {
this.scroll.setVirtualContainer(appDialogsManager.chatList); this.scroll.setVirtualContainer(appDialogsManager.chatList);
this.scroll.onScrolledBottom = this.onChatsScroll.bind(this); this.scroll.onScrolledBottom = this.onChatsScroll.bind(this);
appDialogsManager.chatsHidden = this.scroll.hiddenElements; appDialogsManager.chatsHidden = this.scroll.hiddenElements;
//this.scroll.container.addEventListener('scroll', this.onChatsScroll.bind(this));
this.scrollArchived = new Scrollable(this.chatsArchivedContainer as HTMLDivElement, false, true, 300, 'CLA'); this.scrollArchived = new Scrollable(this.chatsArchivedContainer as HTMLDivElement, false, true, 300, 'CLA');
this.scrollArchived.setVirtualContainer(appDialogsManager.chatListArchived); this.scrollArchived.setVirtualContainer(appDialogsManager.chatListArchived);
@ -134,7 +131,7 @@ class AppSidebarLeft {
for(let i = 0; i < 1000; ++i) { for(let i = 0; i < 1000; ++i) {
let li = document.createElement('li'); let li = document.createElement('li');
li.dataset.id = '' + i; li.dataset.id = '' + i;
li.innerHTML = `<div class="rp"><div class="user-avatar" style="background-color: rgb(166, 149, 231); font-size: 0px;"><img src="blob:https://localhost:9000/ce99a2a3-f34b-4ca1-a09e-f716f89930d8"></div><div class="user-caption"><p><span class="user-title">${i}</span><span><span class="message-status"></span><span class="message-time">18:33</span></span></p><p><span class="user-last-message"><b>Ильяс: </b>Гагагагга</span><span></span></p></div></div>`; li.innerHTML = `<div class="rp"><div class="user-avatar" style="background-color: rgb(166, 149, 231); font-size: 0px;"><img src="#"></div><div class="user-caption"><p><span class="user-title">${i}</span><span><span class="message-status"></span><span class="message-time">18:33</span></span></p><p><span class="user-last-message"><b>-_-_-_-: </b>qweasd</span><span></span></p></div></div>`;
this.scroll.append(li); this.scroll.append(li);
} }
} }

391
src/lib/appManagers/appSidebarRight.ts

@ -1,6 +1,6 @@
import { horizontalMenu, formatPhoneNumber } from "../../components/misc"; import { horizontalMenu, formatPhoneNumber, putPreloader } from "../../components/misc";
import Scrollable from '../../components/scrollable'; import Scrollable from '../../components/scrollable';
import { isElementInViewport, $rootScope } from "../utils"; import { $rootScope } from "../utils";
import appMessagesManager from "./appMessagesManager"; import appMessagesManager from "./appMessagesManager";
import appPhotosManager from "./appPhotosManager"; import appPhotosManager from "./appPhotosManager";
import appPeersManager from "./appPeersManager"; import appPeersManager from "./appPeersManager";
@ -38,13 +38,13 @@ class AppSidebarRight {
contentLinks: this.profileContentEl.querySelector('#content-links') as HTMLDivElement, contentLinks: this.profileContentEl.querySelector('#content-links') as HTMLDivElement,
contentAudio: this.profileContentEl.querySelector('#content-audio') as HTMLDivElement, contentAudio: this.profileContentEl.querySelector('#content-audio') as HTMLDivElement,
}; };
public lastSharedMediaDiv: HTMLDivElement = null; public lastSharedMediaDiv: HTMLDivElement = null;
private loadSidebarMediaPromises: { private loadSidebarMediaPromises: {
[type: string]: Promise<void> [type: string]: Promise<void>
} = {}; } = {};
public sharedMediaTypes = [ public sharedMediaTypes = [
'inputMessagesFilterContacts', 'inputMessagesFilterContacts',
'inputMessagesFilterPhotoVideo', 'inputMessagesFilterPhotoVideo',
@ -54,7 +54,7 @@ class AppSidebarRight {
]; ];
public sharedMediaType: string = ''; public sharedMediaType: string = '';
private sharedMediaSelected: HTMLDivElement = null; private sharedMediaSelected: HTMLDivElement = null;
private lazyLoadQueueSidebar = new LazyLoadQueue(5); private lazyLoadQueueSidebar = new LazyLoadQueue(5);
/* public minMediaID: { /* public minMediaID: {
[type: string]: number [type: string]: number
@ -62,17 +62,17 @@ class AppSidebarRight {
public cleared: { public cleared: {
[type: string]: boolean [type: string]: boolean
} = {}; } = {};
public historiesStorage: { public historiesStorage: {
[peerID: number]: { [peerID: number]: {
[type: string]: number[] [type: string]: number[]
} }
} = {}; } = {};
private log = logger('SR'); private log = logger('SR');
private peerID = 0; private peerID = 0;
public sidebarScroll: Scrollable = null; public sidebarScroll: Scrollable = null;
private savedVirtualStates: { private savedVirtualStates: {
[id: number]: { [id: number]: {
@ -80,25 +80,37 @@ class AppSidebarRight {
paddings: any paddings: any
} }
} = {}; } = {};
private profileTabs: HTMLUListElement; private profileTabs: HTMLUListElement;
private prevTabID = -1; private prevTabID = -1;
private mediaDivsByIDs: { private mediaDivsByIDs: {
[mid: number]: HTMLDivElement [mid: number]: HTMLDivElement
} = {}; } = {};
constructor() { constructor() {
let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement; let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement;
this.profileTabs = this.profileContentEl.querySelector('.profile-tabs') as HTMLUListElement; this.profileTabs = this.profileContentEl.querySelector('.profile-tabs') as HTMLUListElement;
this.sidebarScroll = new Scrollable(this.sidebarEl, false, true, 500, 'SR'); this.sidebarScroll = new Scrollable(this.sidebarEl, false, true, 500, 'SR');
this.sidebarScroll.container.addEventListener('scroll', this.onSidebarScroll.bind(this)); this.sidebarScroll.container.addEventListener('scroll', this.onSidebarScroll.bind(this));
this.sidebarScroll.onScrolledBottom = () => {
if(this.sharedMediaSelected && !this.sidebarScroll.hiddenElements.down.length
&& this.sharedMediaSelected.childElementCount/* && false */) {
this.loadSidebarMedia(true);
}
};
horizontalMenu(this.profileTabs, container, (id, tabContent) => { horizontalMenu(this.profileTabs, container, (id, tabContent) => {
if(this.prevTabID == id) return;
this.sharedMediaType = this.sharedMediaTypes[id]; this.sharedMediaType = this.sharedMediaTypes[id];
this.sharedMediaSelected = tabContent.firstElementChild as HTMLDivElement; this.sharedMediaSelected = tabContent.firstElementChild as HTMLDivElement;
if(this.prevTabID != -1 && !this.sharedMediaSelected.childElementCount) { // quick brown fix
this.loadSidebarMedia(true);
}
if(this.prevTabID != -1) { if(this.prevTabID != -1) {
this.savedVirtualStates[this.prevTabID] = { this.savedVirtualStates[this.prevTabID] = {
hiddenElements: { hiddenElements: {
@ -111,254 +123,248 @@ class AppSidebarRight {
} }
}; };
} }
this.prevTabID = id; this.prevTabID = id;
//this.log('setVirtualContainer', id, this.sharedMediaSelected); this.log('setVirtualContainer', id, this.sharedMediaSelected);
this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected); this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected);
if(this.savedVirtualStates[id]) { if(this.savedVirtualStates[id]) {
this.log(this.savedVirtualStates[id]); this.log(this.savedVirtualStates[id]);
this.sidebarScroll.hiddenElements = this.savedVirtualStates[id].hiddenElements; this.sidebarScroll.hiddenElements = this.savedVirtualStates[id].hiddenElements;
this.sidebarScroll.paddings = this.savedVirtualStates[id].paddings; this.sidebarScroll.paddings = this.savedVirtualStates[id].paddings;
} }
}, this.onSidebarScroll.bind(this)); }, this.onSidebarScroll.bind(this));
//(this.profileTabs.children[1] as HTMLLIElement).click(); // set media
let sidebarCloseBtn = this.sidebarEl.querySelector('.sidebar-close-button') as HTMLButtonElement; let sidebarCloseBtn = this.sidebarEl.querySelector('.sidebar-close-button') as HTMLButtonElement;
sidebarCloseBtn.addEventListener('click', () => { sidebarCloseBtn.addEventListener('click', () => {
this.toggleSidebar(false); this.toggleSidebar(false);
}); });
this.sharedMedia.contentMedia.addEventListener('click', (e) => { this.sharedMedia.contentMedia.addEventListener('click', (e) => {
let target = e.target as HTMLDivElement; let target = e.target as HTMLDivElement;
let messageID = +target.getAttribute('message-id'); let messageID = +target.getAttribute('message-id');
if(!messageID) { if(!messageID) {
this.log.warn('no messageID by click on target:', target); this.log.warn('no messageID by click on target:', target);
return; return;
} }
let message = appMessagesManager.getMessage(messageID); let message = appMessagesManager.getMessage(messageID);
let ids = Object.keys(this.mediaDivsByIDs).map(k => +k).sort(); let ids = Object.keys(this.mediaDivsByIDs).map(k => +k).sort();
let idx = ids.findIndex(i => i == messageID); let idx = ids.findIndex(i => i == messageID);
let prev = ids[idx + 1] || null; let prev = ids[idx + 1] || null;
let next = ids[idx - 1] || null; let next = ids[idx - 1] || null;
appMediaViewer.openMedia(message, target, this.mediaDivsByIDs[prev] || null, this.mediaDivsByIDs[next] || null); appMediaViewer.openMedia(message, target, this.mediaDivsByIDs[prev] || null, this.mediaDivsByIDs[next] || null);
}); });
this.profileElements.notificationsCheckbox.addEventListener('change', () => { this.profileElements.notificationsCheckbox.addEventListener('change', () => {
let checked = this.profileElements.notificationsCheckbox.checked; //let checked = this.profileElements.notificationsCheckbox.checked;
appImManager.mutePeer(); appImManager.mutePeer();
}); });
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
setTimeout(() => { setTimeout(() => {
this.sidebarScroll.onScroll(); this.sidebarScroll.onScroll();
this.onSidebarScroll(); this.onSidebarScroll();
}, 0); }, 0);
}); });
if(testScroll) { if(testScroll) {
let div = document.createElement('div'); let div = document.createElement('div');
for(let i = 0; i < 500; ++i) { for(let i = 0; i < 500; ++i) {
//div.insertAdjacentHTML('beforeend', `<div message-id="0" style="background-image: url(assets/img/camomile.jpg);"></div>`); //div.insertAdjacentHTML('beforeend', `<div message-id="0" style="background-image: url(assets/img/camomile.jpg);"></div>`);
div.insertAdjacentHTML('beforeend', `<div data-id="${i / 3 | 0}">${i / 3 | 0}</div>`); div.insertAdjacentHTML('beforeend', `<div data-id="${i / 3 | 0}">${i / 3 | 0}</div>`);
if((i + 1) % 3 == 0) { if((i + 1) % 3 == 0) {
this.sharedMedia.contentMedia.append(div); this.sharedMedia.contentMedia.append(div);
div = document.createElement('div'); div = document.createElement('div');
} }
div.dataset.id = '' + (i / 3 | 0); div.dataset.id = '' + (i / 3 | 0);
} }
this.sharedMedia.contentMedia.append(div); this.sharedMedia.contentMedia.append(div);
(this.profileTabs.children[1] as HTMLLIElement).click(); // set media (this.profileTabs.children[1] as HTMLLIElement).click(); // set media
} }
} }
public onSidebarScroll() { public onSidebarScroll() {
this.lazyLoadQueueSidebar.check(); this.lazyLoadQueueSidebar.check();
if(this.sharedMediaSelected && !this.sidebarScroll.hiddenElements.down.length/* && false */) {
let media = Array.from(this.sharedMediaSelected.childNodes).slice(-15);
for(let div of media) {
if(isElementInViewport(div)) {
//this.log('Will load more media');
this.loadSidebarMedia(true);
break;
}
}
}
} }
public toggleSidebar(enable?: boolean) { public toggleSidebar(enable?: boolean) {
/////this.log('sidebarEl', this.sidebarEl, enable, isElementInViewport(this.sidebarEl)); /////this.log('sidebarEl', this.sidebarEl, enable, isElementInViewport(this.sidebarEl));
/* if(enable !== undefined) {
this.sidebarEl.style.display = enable ? 'block' : 'none';
return;
}
this.sidebarEl.style.display = isElementInViewport(this.sidebarEl) ? 'none' : 'block'; */
if(enable !== undefined) { if(enable !== undefined) {
this.sidebarEl.style.width = enable ? '25%' : '0%'; if(enable) this.sidebarEl.classList.add('active');
else this.sidebarEl.classList.remove('active');
return; return;
} }
this.sidebarEl.style.width = isElementInViewport(this.sidebarEl) ? '0%' : '25%'; if(this.sidebarEl.classList.contains('active')) {
this.sidebarEl.classList.remove('active');
} else {
this.sidebarEl.classList.add('active');
}
} }
public loadSidebarMedia(single = false) { public loadSidebarMedia(single = false) {
if(testScroll) { if(testScroll /* || 1 == 1 */) {
return; return;
} }
//this.log('loadSidebarMedia', single, this.peerID);
let peerID = this.peerID; let peerID = this.peerID;
let typesToLoad = single ? [this.sharedMediaType] : this.sharedMediaTypes; let typesToLoad = single ? [this.sharedMediaType] : this.sharedMediaTypes;
if(!this.historiesStorage[peerID]) this.historiesStorage[peerID] = {}; if(!this.historiesStorage[peerID]) this.historiesStorage[peerID] = {};
let historyStorage = this.historiesStorage[peerID]; let historyStorage = this.historiesStorage[peerID];
let promises = typesToLoad.map(type => { let promises = typesToLoad.map(type => {
if(this.loadSidebarMediaPromises[type]) return this.loadSidebarMediaPromises[type]; if(this.loadSidebarMediaPromises[type]) return this.loadSidebarMediaPromises[type];
if(!historyStorage[type]) historyStorage[type] = []; if(!historyStorage[type]) historyStorage[type] = [];
let history = historyStorage[type]; let history = historyStorage[type];
// заливать новую картинку сюда только после полной отправки! // заливать новую картинку сюда только после полной отправки!
//let maxID = this.minMediaID[type] || 0; //let maxID = this.minMediaID[type] || 0;
let maxID = history[history.length - 1] || 0; let maxID = history[history.length - 1] || 0;
let ids = !maxID && appMessagesManager.historiesStorage[peerID] let ids = !maxID && appMessagesManager.historiesStorage[peerID]
? appMessagesManager.historiesStorage[peerID].history.slice() : []; ? appMessagesManager.historiesStorage[peerID].history.slice() : [];
maxID = !maxID && ids.length ? ids[ids.length - 1] : maxID; maxID = !maxID && ids.length ? ids[ids.length - 1] : maxID;
//this.log('search house of glass pre', type, ids, maxID); //this.log('search house of glass pre', type, ids, maxID);
return this.loadSidebarMediaPromises[type] = appMessagesManager.getSearch(peerID, '', {_: type}, maxID, 50) return this.loadSidebarMediaPromises[type] = appMessagesManager.getSearch(peerID, '', {_: type}, maxID, history.length ? 50 : 15)
.then(value => { .then(value => {
ids = ids.concat(value.history); ids = ids.concat(value.history);
history.push(...ids); history.push(...ids);
//this.log('search house of glass', type, value, ids, this.cleared); //this.log('search house of glass', type, value, ids, this.cleared);
if($rootScope.selectedPeerID != peerID) { if($rootScope.selectedPeerID != peerID) {
this.log.warn('peer changed'); this.log.warn('peer changed');
return; return;
} }
if(this.cleared[type]) { if(this.cleared[type]) {
ids = history; ids = history;
delete this.cleared[type]; delete this.cleared[type];
} }
ids.forEach(mid => { let sharedMediaDiv: HTMLDivElement;
//this.minMediaID[type] = mid; let messages: any[] = [];
for(let mid of ids) {
let message = appMessagesManager.getMessage(mid); let message = appMessagesManager.getMessage(mid);
if(!message.media) return; if(message.media) messages.push(message);
}
/*'inputMessagesFilterContacts',
'inputMessagesFilterPhotoVideo', /*'inputMessagesFilterContacts',
'inputMessagesFilterDocument', 'inputMessagesFilterPhotoVideo',
'inputMessagesFilterUrl', 'inputMessagesFilterDocument',
'inputMessagesFilterVoice'*/ 'inputMessagesFilterUrl',
switch(type) { 'inputMessagesFilterVoice'*/
case 'inputMessagesFilterPhotoVideo': { switch(type) {
/* if(!(message.media.photo || message.media.document || message.media.webpage.document)) { case 'inputMessagesFilterPhotoVideo': {
this.log.error('no media!', message); sharedMediaDiv = this.sharedMedia.contentMedia;
break;
} */ for(let message of messages) {
let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document); let media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
if(!media) { if(!media) {
//this.log('no media!', message); //this.log('no media!', message);
break; continue;;
} }
if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) { if(media._ == 'document' && media.type != 'video'/* && media.type != 'gif' */) {
//this.log('broken video', media); //this.log('broken video', media);
break; continue;
} }
let div = document.createElement('div'); let div = document.createElement('div');
//console.log(message, photo); //console.log(message, photo);
let sizes = media.sizes || media.thumbs; let sizes = media.sizes || media.thumbs;
if(sizes && sizes[0].bytes) { if(sizes && sizes[0].bytes) {
appPhotosManager.setAttachmentPreview(sizes[0].bytes, div, false, true); appPhotosManager.setAttachmentPreview(sizes[0].bytes, div, false, true);
} /* else { } /* else {
this.log('no stripped size', message, media); this.log('no stripped size', message, media);
} */ } */
//this.log('inputMessagesFilterPhotoVideo', message, media); //this.log('inputMessagesFilterPhotoVideo', message, media);
let load = () => appPhotosManager.preloadPhoto(media, appPhotosManager.choosePhotoSize(media, 380, 0)) let load = () => appPhotosManager.preloadPhoto(media, appPhotosManager.choosePhotoSize(media, 380, 0))
.then((blob) => { .then((blob) => {
if($rootScope.selectedPeerID != peerID) { if($rootScope.selectedPeerID != peerID) {
this.log.warn('peer changed'); this.log.warn('peer changed');
return; return;
} }
div.style.backgroundImage = 'url(' + URL.createObjectURL(blob) + ')'; div.style.backgroundImage = 'url(' + URL.createObjectURL(blob) + ')';
}); });
div.setAttribute('message-id', '' + mid); div.setAttribute('message-id', '' + message.mid);
this.lazyLoadQueueSidebar.push({div, load}); this.lazyLoadQueueSidebar.push({div, load});
this.lastSharedMediaDiv.append(div); this.lastSharedMediaDiv.append(div);
if(this.lastSharedMediaDiv.childElementCount == 3) { if(this.lastSharedMediaDiv.childElementCount == 3) {
this.sharedMedia.contentMedia.append(this.lastSharedMediaDiv); this.sidebarScroll.append(this.lastSharedMediaDiv);
this.lastSharedMediaDiv = document.createElement('div'); this.lastSharedMediaDiv = document.createElement('div');
} }
this.mediaDivsByIDs[mid] = div; this.mediaDivsByIDs[message.mid] = div;
//this.sharedMedia.contentMedia.append(div); //sharedMediaDiv.append(div);
break;
} }
case 'inputMessagesFilterDocument': { break;
}
case 'inputMessagesFilterDocument': {
sharedMediaDiv = this.sharedMedia.contentDocuments;
for(let message of messages) {
if(!message.media.document || message.media.document.type == 'voice') { if(!message.media.document || message.media.document.type == 'voice') {
break; continue;
} }
let doc = message.media.document; let doc = message.media.document;
if(doc.attributes) { if(doc.attributes) {
if(doc.attributes.find((a: any) => a._ == "documentAttributeSticker")) { if(doc.attributes.find((a: any) => a._ == "documentAttributeSticker")) {
break; continue;
} }
} }
//this.log('come back down to my knees', message); //this.log('come back down to my knees', message);
let div = wrapDocument(message.media.document, true); let div = wrapDocument(message.media.document, true);
this.sharedMedia.contentDocuments.append(div); this.sidebarScroll.append(div);
break;
} }
break;
}
case 'inputMessagesFilterUrl': {
sharedMediaDiv = this.sharedMedia.contentLinks;
case 'inputMessagesFilterUrl': { for(let message of messages) {
if(!message.media.webpage || message.media.webpage._ == 'webPageEmpty') { if(!message.media.webpage || message.media.webpage._ == 'webPageEmpty') {
break; continue;
} }
let webpage = message.media.webpage; let webpage = message.media.webpage;
let div = document.createElement('div'); let div = document.createElement('div');
let previewDiv = document.createElement('div'); let previewDiv = document.createElement('div');
previewDiv.classList.add('preview'); previewDiv.classList.add('preview');
//this.log('wrapping webpage', webpage); //this.log('wrapping webpage', webpage);
if(webpage.photo) { if(webpage.photo) {
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 380, 0)) let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 380, 0))
.then((blob) => { .then((blob) => {
@ -366,61 +372,69 @@ class AppSidebarRight {
this.log.warn('peer changed'); this.log.warn('peer changed');
return; return;
} }
previewDiv.style.backgroundImage = 'url(' + URL.createObjectURL(blob) + ')'; previewDiv.style.backgroundImage = 'url(' + URL.createObjectURL(blob) + ')';
}); });
this.lazyLoadQueueSidebar.push({div: previewDiv, load}); this.lazyLoadQueueSidebar.push({div: previewDiv, load});
} else { } else {
previewDiv.innerText = (webpage.title || webpage.description || webpage.url || webpage.display_url).slice(0, 1); previewDiv.innerText = (webpage.title || webpage.description || webpage.url || webpage.display_url).slice(0, 1);
previewDiv.classList.add('empty'); previewDiv.classList.add('empty');
} }
let title = webpage.rTitle || ''; let title = webpage.rTitle || '';
let subtitle = webpage.rDescription || ''; let subtitle = webpage.rDescription || '';
let url = RichTextProcessor.wrapRichText(webpage.url || ''); let url = RichTextProcessor.wrapRichText(webpage.url || '');
if(!title) { if(!title) {
//title = new URL(webpage.url).hostname; //title = new URL(webpage.url).hostname;
title = webpage.display_url.split('/', 1)[0]; title = webpage.display_url.split('/', 1)[0];
} }
div.append(previewDiv); div.append(previewDiv);
div.insertAdjacentHTML('beforeend', ` div.insertAdjacentHTML('beforeend', `
<div class="title">${title}</div> <div class="title">${title}</div>
<div class="subtitle">${subtitle}</div> <div class="subtitle">${subtitle}</div>
<div class="url">${url}</div> <div class="url">${url}</div>
`); `);
if(div.innerText.trim().length) { if(div.innerText.trim().length) {
this.sharedMedia.contentLinks.append(div); this.sidebarScroll.append(div);
} }
break;
} }
/* case 'inputMessagesFilterVoice': {
//this.log('wrapping audio', message.media);
if(!message.media || !message.media.document || message.media.document.type != 'voice') {
break;
}
let doc = message.media.document;
this.log('wrapping audio', doc);
let audioDiv = wrapAudio(doc);
this.sharedMedia.contentAudio.append(audioDiv);
break;
} */
default: break;
//console.warn('death is my friend', message); }
/* case 'inputMessagesFilterVoice': {
//this.log('wrapping audio', message.media);
if(!message.media || !message.media.document || message.media.document.type != 'voice') {
break; break;
}
let doc = message.media.document;
this.log('wrapping audio', doc);
let audioDiv = wrapAudio(doc);
this.sharedMedia.contentAudio.append(audioDiv);
break;
} */
default:
//console.warn('death is my friend', message);
break;
}
if(sharedMediaDiv) {
let parent = sharedMediaDiv.parentElement;
if(parent.lastElementChild.classList.contains('preloader')) {
parent.lastElementChild.remove();
} }
}); }
this.onSidebarScroll(); this.onSidebarScroll();
}).then(() => { }).then(() => {
@ -430,26 +444,17 @@ class AppSidebarRight {
this.loadSidebarMediaPromises[type] = null; this.loadSidebarMediaPromises[type] = null;
}); });
}); });
return promises; return promises;
} }
public fillProfileElements() { public fillProfileElements() {
let peerID = this.peerID = $rootScope.selectedPeerID; let peerID = this.peerID = $rootScope.selectedPeerID;
this.loadSidebarMediaPromises = {}; this.loadSidebarMediaPromises = {};
this.lastSharedMediaDiv = document.createElement('div'); this.lastSharedMediaDiv = document.createElement('div');
//this.log('fillProfileElements'); //this.log('fillProfileElements');
this.savedVirtualStates = {};
this.prevTabID = -1;
this.sidebarScroll.setVirtualContainer(null);
(this.profileTabs.children[1] as HTMLLIElement).click(); // set media
if(this.sharedMediaSelected) {
//this.sidebarScroll.setVirtualContainer(this.sharedMediaSelected);
}
this.profileContentEl.parentElement.scrollTop = 0; this.profileContentEl.parentElement.scrollTop = 0;
this.profileElements.bio.style.display = 'none'; this.profileElements.bio.style.display = 'none';
this.profileElements.phone.style.display = 'none'; this.profileElements.phone.style.display = 'none';
@ -457,40 +462,48 @@ class AppSidebarRight {
this.profileElements.notificationsRow.style.display = ''; this.profileElements.notificationsRow.style.display = '';
this.profileElements.notificationsCheckbox.checked = true; this.profileElements.notificationsCheckbox.checked = true;
this.profileElements.notificationsStatus.innerText = 'Enabled'; this.profileElements.notificationsStatus.innerText = 'Enabled';
this.mediaDivsByIDs = {}; this.mediaDivsByIDs = {};
this.lazyLoadQueueSidebar.clear(); this.lazyLoadQueueSidebar.clear();
Object.keys(this.sharedMedia).forEach(key => { Object.keys(this.sharedMedia).forEach(key => {
this.sharedMedia[key].innerHTML = ''; this.sharedMedia[key].innerHTML = '';
let parent = this.sharedMedia[key].parentElement;
if(!parent.querySelector('.preloader')) {
putPreloader(parent, true);
}
}); });
this.sharedMediaTypes.forEach(type => { this.sharedMediaTypes.forEach(type => {
//this.minMediaID[type] = 0; //this.minMediaID[type] = 0;
this.cleared[type] = true; this.cleared[type] = true;
}); });
this.savedVirtualStates = {};
this.prevTabID = -1;
this.sidebarScroll.setVirtualContainer(null);
(this.profileTabs.children[1] as HTMLLIElement).click(); // set media
let setText = (text: string, el: HTMLDivElement) => { let setText = (text: string, el: HTMLDivElement) => {
el.style.display = ''; el.style.display = '';
if(el.childElementCount > 1) { if(el.childElementCount > 1) {
el.firstElementChild.remove(); el.firstElementChild.remove();
} }
let p = document.createElement('p'); let p = document.createElement('p');
p.innerHTML = text; p.innerHTML = text;
el.prepend(p); el.prepend(p);
}; };
// username // username
if(peerID != appImManager.myID) { if(peerID != appImManager.myID) {
let username = appPeersManager.getPeerUsername(peerID); let username = appPeersManager.getPeerUsername(peerID);
if(username) { if(username) {
setText(appPeersManager.getPeerUsername(peerID), this.profileElements.username); setText(appPeersManager.getPeerUsername(peerID), this.profileElements.username);
} }
}
if(peerID != appImManager.myID) {
let dialog: any = appMessagesManager.getDialogByPeerID(peerID); let dialog: any = appMessagesManager.getDialogByPeerID(peerID);
if(dialog.length) { if(dialog.length) {
dialog = dialog[0]; dialog = dialog[0];
@ -498,57 +511,57 @@ class AppSidebarRight {
if(dialog.notify_settings && dialog.notify_settings.mute_until) { if(dialog.notify_settings && dialog.notify_settings.mute_until) {
muted = new Date(dialog.notify_settings.mute_until * 1000) > new Date(); muted = new Date(dialog.notify_settings.mute_until * 1000) > new Date();
} }
appImManager.setMutedState(muted); appImManager.setMutedState(muted);
} }
} else { } else {
this.profileElements.notificationsRow.style.display = 'none'; this.profileElements.notificationsRow.style.display = 'none';
} }
if(peerID > 0) { if(peerID > 0) {
let user = appUsersManager.getUser(peerID); let user = appUsersManager.getUser(peerID);
if(user.phone && peerID != appImManager.myID) { if(user.phone && peerID != appImManager.myID) {
setText('+' + formatPhoneNumber(user.phone).formatted, this.profileElements.phone); setText('+' + formatPhoneNumber(user.phone).formatted, this.profileElements.phone);
} }
appProfileManager.getProfile(peerID, true).then(userFull => { appProfileManager.getProfile(peerID, true).then(userFull => {
if(this.peerID != peerID) { if(this.peerID != peerID) {
this.log.warn('peer changed'); this.log.warn('peer changed');
return; return;
} }
if(userFull.rAbout && peerID != appImManager.myID) { if(userFull.rAbout && peerID != appImManager.myID) {
setText(userFull.rAbout, this.profileElements.bio); setText(userFull.rAbout, this.profileElements.bio);
} }
//this.log('userFull', userFull); //this.log('userFull', userFull);
if(userFull.pinned_msg_id) { // request pinned message if(userFull.pinned_msg_id) { // request pinned message
appImManager.pinnedMsgID = userFull.pinned_msg_id; appImManager.pinnedMsgID = userFull.pinned_msg_id;
appMessagesManager.wrapSingleMessage(userFull.pinned_msg_id); appMessagesManager.wrapSingleMessage(userFull.pinned_msg_id);
} }
this.sidebarScroll.getScrollTopOffset(); this.sidebarScroll.getScrollTopOffset();
}); });
} else { } else {
let chat = appPeersManager.getPeer(peerID); let chat = appPeersManager.getPeer(peerID);
appProfileManager.getChatFull(chat.id).then((chatFull: any) => { appProfileManager.getChatFull(chat.id).then((chatFull: any) => {
if(this.peerID != peerID) { if(this.peerID != peerID) {
this.log.warn('peer changed'); this.log.warn('peer changed');
return; return;
} }
//this.log('chatInfo res 2:', chatFull); //this.log('chatInfo res 2:', chatFull);
if(chatFull.about) { if(chatFull.about) {
setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio); setText(RichTextProcessor.wrapRichText(chatFull.about), this.profileElements.bio);
} }
this.sidebarScroll.getScrollTopOffset(); this.sidebarScroll.getScrollTopOffset();
}); });
} }
this.sidebarScroll.getScrollTopOffset(); this.sidebarScroll.getScrollTopOffset();
//this.loadSidebarMedia(); //this.loadSidebarMedia();
} }

12
src/lib/ckin.js

@ -3,18 +3,6 @@
NodeList.prototype.forEach = Array.prototype.forEach; NodeList.prototype.forEach = Array.prototype.forEach;
})(); })();
String.prototype.toHHMMSS = function(leadZero) {
let sec_num = parseInt(this, 10);
let hours = Math.floor(sec_num / 3600);
let minutes = Math.floor((sec_num - (hours * 3600)) / 60);
let seconds = sec_num - (hours * 3600) - (minutes * 60);
if(hours < 10) hours = "0" + hours;
if(minutes < 10) minutes = leadZero ? "0" + minutes : minutes;
if(seconds < 10) seconds = "0" + seconds;
return minutes + ':' + seconds;
}
function stylePlayer(player, video) { function stylePlayer(player, video) {
let skin = attachSkin(video.dataset.ckin); let skin = attachSkin(video.dataset.ckin);
player.classList.add(skin); player.classList.add(skin);

4
src/lib/lottieLoader.ts

@ -33,9 +33,9 @@ class LottieLoader {
for(let i = length - 1; i >= 0; --i) { for(let i = length - 1; i >= 0; --i) {
let {animation, container, paused, autoplay, canvas} = animations[i]; let {animation, container, paused, autoplay, canvas} = animations[i];
if(canvas && isElementInViewport(container)) { if(canvas) {
let c = container.firstElementChild as HTMLCanvasElement; let c = container.firstElementChild as HTMLCanvasElement;
if(!c.height && !c.width) { if(!c.height && !c.width && isElementInViewport(container)) {
//console.log('lottie need resize'); //console.log('lottie need resize');
animation.resize(); animation.resize();
} }

22
src/lib/polyfill.ts

@ -53,6 +53,23 @@ Array.prototype.forEachReverse = function<T>(callback: (value: T, index?: number
} }
}; };
Array.prototype.findAndSplice = function<T>(verify: (value: T, index?: number, array?: Array<T>) => boolean) {
let index = this.findIndex(verify);
return index !== -1 ? this.splice(index, 1)[0] : undefined;
};
String.prototype.toHHMMSS = function(leadZero = false) {
let sec_num = parseInt(this + '', 10);
let hours: any = Math.floor(sec_num / 3600);
let minutes: any = Math.floor((sec_num - (hours * 3600)) / 60);
let seconds: any = sec_num - (hours * 3600) - (minutes * 60);
if(hours < 10) hours = "0" + hours;
if(minutes < 10) minutes = leadZero ? "0" + minutes : minutes;
if(seconds < 10) seconds = "0" + seconds;
return minutes + ':' + seconds;
}
declare global { declare global {
interface Uint8Array { interface Uint8Array {
hex: string; hex: string;
@ -62,5 +79,10 @@ declare global {
interface Array<T> { interface Array<T> {
forEachReverse(callback: (value: T, index?: number, array?: Array<T>) => void): void; forEachReverse(callback: (value: T, index?: number, array?: Array<T>) => void): void;
findAndSplice(verify: (value: T, index?: number, array?: Array<T>) => boolean): T;
}
interface String {
toHHMMSS(leadZero?: boolean): string;
} }
} }

2
src/lib/utils.js

@ -297,7 +297,7 @@ export function getSelectedText() {
export const $rootScope = { export const $rootScope = {
$broadcast: (name/* : string */, detail/*? : any */) => { $broadcast: (name/* : string */, detail/*? : any */) => {
////console.log(dT(), 'Broadcasting ' + name + ' event, with args:', detail); //console.log(dT(), 'Broadcasting ' + name + ' event, with args:', detail);
//console.trace(); //console.trace();
let myCustomEvent = new CustomEvent(name, {detail}); let myCustomEvent = new CustomEvent(name, {detail});
document.dispatchEvent(myCustomEvent); document.dispatchEvent(myCustomEvent);

40
src/scss/partials/_chat.scss

@ -370,8 +370,8 @@
cursor: pointer; cursor: pointer;
background: none!important; background: none!important;
box-shadow: none; box-shadow: none;
max-width: 300px; /* max-width: 300px;
max-height: 300px; max-height: 300px; */
} }
img { img {
@ -387,6 +387,13 @@
} }
} }
&.sticker {
.bubble__container {
max-width: 200px;
max-height: 200px;
}
}
&.round { &.round {
.attachment { .attachment {
max-width: 200px; max-width: 200px;
@ -702,11 +709,11 @@
/* padding-bottom: 4px; */ /* padding-bottom: 4px; */
color: $darkblue; color: $darkblue;
font-size: .9rem; font-size: .9rem;
width: max-content;
max-width: 100%; max-width: 100%;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; //width: max-content;
//white-space: nowrap;
} }
&:not(.webpage) { &:not(.webpage) {
@ -732,16 +739,25 @@
margin-top: 6px; margin-top: 6px;
} }
&:not(.sticker):not(.emoji-big):not(.round):last-child .bubble__container:after { &:not(.sticker):not(.emoji-big):not(.round).is-group-last .bubble__container:after {
position: absolute; position: absolute;
bottom: -1px; bottom: 0;
width: 11px; width: 11px;
height: 20px; height: 20px;
background-repeat: no-repeat repeat; background-repeat: no-repeat repeat;
content: ''; content: '';
background-size: 11px 20px; background-size: 11px 20px;
background-position-y: 1px;
} }
} }
.bubble-audio.is-in .time {
width: inherit;
}
.bubble-audio.is-out .time {
width: inherit;
}
/* .bubble + .bubble { /* .bubble + .bubble {
margin-top: 5px; margin-top: 5px;
@ -761,11 +777,11 @@
border-radius: 6px 12px 12px 6px; border-radius: 6px 12px 12px 6px;
} }
&:first-child .bubble__container { &.is-group-first .bubble__container {
border-radius: 12px 12px 12px 6px; border-radius: 12px 12px 12px 6px;
} }
&:last-child .bubble__container { &.is-group-last .bubble__container {
border-radius: 6px 12px 12px 0px; border-radius: 6px 12px 12px 0px;
//border-radius: 12px 12px 12px 0px; //border-radius: 12px 12px 12px 0px;
@ -775,7 +791,7 @@
} }
} }
&:first-child:last-child .bubble__container { &.is-group-first.is-group-last .bubble__container {
border-radius: 12px 12px 12px 0px; border-radius: 12px 12px 12px 0px;
} }
@ -835,11 +851,11 @@
border-radius: 12px 6px 6px 12px; border-radius: 12px 6px 6px 12px;
} }
&:first-child .bubble__container { &.is-group-first .bubble__container {
border-radius: 12px 12px 6px 12px; border-radius: 12px 12px 6px 12px;
} }
&:last-child .bubble__container { &.is-group-last .bubble__container {
border-radius: 12px 6px 0px 12px; border-radius: 12px 6px 0px 12px;
&:after { &:after {
@ -848,7 +864,7 @@
} }
} }
&:first-child:last-child .bubble__container { &.is-group-first.is-group-last .bubble__container {
border-radius: 12px 12px 0px 12px; border-radius: 12px 12px 0px 12px;
} }

286
src/scss/partials/_rightSIdebar.scss

@ -0,0 +1,286 @@
.profile-container {
width: 0%;
/* grid-column: 3; */
position: relative;
transition: .2s ease-in-out;
> .scrollable {
min-width: 25vw;
display: flex;
flex-direction: column;
}
@media (min-width: $large-screen) {
> .scrollable {
min-width: calc(#{$large-screen} / 4 - 1px);
}
}
&:not(.active) {
border-left-width: 0;
}
&.active {
width: 25%;
}
.sidebar-header {
flex: 0 0 auto;
}
}
.profile-content {
flex: 1 1 auto;
display: flex;
flex-direction: column;
.profile-name {
text-align: center;
font-size: 23px;
font-weight: 500;
margin-bottom: 3px;
span.emoji {
vertical-align: inherit;
min-width: min-content;
}
}
.profile-subtitle {
text-align: center;
color: $darkgrey;
font-size: 14px;
&.online {
color: $darkblue;
}
}
.profile-row {
display: flex;
width: 100%;
flex-direction: column;
padding-left: 80px;
padding-top: 2px;
padding-right: 12px;
font-size: 15px;
position: relative;
margin-top: 1.75rem;
&:before {
position: absolute;
left: 24px;
/* top: 0; */
font-size: 24px;
color: $darkgrey;
}
p {
color: #000;
margin: 0;
}
&-bio {
.emoji {
width: 24px;
height: 24px;
}
}
}
p.profile-row-label {
color: $placeholder-color;
font-size: 14px;
margin-top: 1px;
}
.user-avatar {
width: 120px;
height: 120px;
margin: 0 auto 20px;
font-size: 4rem!important;
}
[type="checkbox"] + span {
padding-left: 54px;
margin-left: -54px;
}
.content-container {
width: 100%;
max-width: 100%;
overflow: hidden;
flex: 1;
}
.profile-tabs {
margin-top: 40px;
}
.profile-tabs-content {
height: 100%;
/* width: 500%;
margin-left: -100%;
*/
/* > div {
height: 0;
&.active {
height: auto;
}
} */
> div {
height: 100%;
position: relative;
}
/* > div > div:not(.scroll-padding) {
height: 100%;
} */
.preloader {
padding: 0;
position: absolute;
height: 100%;
> svg {
height: 50px;
width: 50px;
}
}
#content-media {
width: 100%;
display: flex;
flex-direction: column;
padding-top: 4px;
> div {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: max-content;
grid-gap: 3.5px;
place-items: start;
padding-top: 3.5px;
> div {
width: 100%;
cursor: pointer;
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
display: flex;
background-color: #cecece;
justify-content: center;
align-items: center;
&::before {
content: "";
display: inline-block;
width: 1px;
height: 0;
padding-bottom: 100%;
}
}
}
}
#content-docs {
padding: 7px 20px;
.document {
padding-left: 4rem;
padding-right: 1rem;
//height: 54px;
height: calc(50px + 1.5rem);
&-ico, &-download {
width: 48px;
height: 48px;
}
/* & + .document {
margin-top: 1.5rem;
} */
}
.document-name {
font-weight: normal;
width: 100%;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
}
#content-links {
padding: 0 30px 15px 15px;
> div {
display: flex;
flex-direction: column;
margin-top: 20px;
margin-left: 5px;
padding-bottom: 2px;
//padding-bottom: 10px;
position: relative;
padding-left: 60px;
overflow: hidden;
//min-height: 48px;
min-height: 58px;
.preview {
height: 48px;
width: 48px;
border-radius: 5px;
overflow: hidden;
position: absolute;
left: 0;
top: 0;
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
&.empty {
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
color: #fff;
text-transform: uppercase;
background-color: $blue;
}
}
.url {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
}
.title {
font-size: 16px;
margin-top: 3px;
}
.subtitle {
font-size: 14px;
}
}
#content-audio {
padding: 0 15px 15px 15px;
> div {
margin-top: 15px;
padding-bottom: 10px;
min-height: 60px;
}
}
}
}

231
src/scss/partials/_sidebar.scss

@ -29,234 +29,3 @@
margin-left: .5rem; margin-left: .5rem;
} }
} }
.profile-content {
.profile-name {
text-align: center;
font-size: 23px;
font-weight: 500;
margin: 3px 0;
span.emoji {
vertical-align: inherit;
min-width: min-content;
}
}
.profile-subtitle {
text-align: center;
color: $darkgrey;
font-size: 14px;
margin: 0 0 18px;
&.online {
color: $darkblue;
}
}
.profile-row {
display: flex;
width: 100%;
flex-direction: column;
padding-left: 80px;
padding-top: 2px;
padding-right: 12px;
font-size: 15px;
position: relative;
margin: 1.75rem 0;
&:before {
position: absolute;
left: 24px;
/* top: 0; */
font-size: 24px;
color: $darkgrey;
}
p {
color: #000;
margin: 0;
}
.profile-row-label {
color: $placeholder-color;
font-size: 14px;
margin-top: 1px;
}
}
.profile-row-bio {
.emoji {
width: 24px;
height: 24px;
}
}
.user-avatar {
width: 120px;
height: 120px;
margin: 0 auto 20px;
font-size: 4rem!important;
}
[type="checkbox"] + span {
padding-left: 54px;
margin-left: -54px;
}
.content-container {
width: 100%;
max-width: 100%;
overflow: hidden;
}
.profile-tabs {
margin-top: 40px;
}
.profile-tabs-content {
/* width: 500%;
margin-left: -100%;
*/
/* > div {
height: 0;
&.active {
height: auto;
}
} */
#content-media {
width: 100%;
display: flex;
flex-direction: column;
padding-top: 4px;
> div {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: max-content;
grid-gap: 3.5px;
place-items: start;
padding-top: 3.5px;
> div {
width: 100%;
cursor: pointer;
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
display: flex;
background-color: #cecece;
justify-content: center;
align-items: center;
&::before {
content: "";
display: inline-block;
width: 1px;
height: 0;
padding-bottom: 100%;
}
}
}
}
#content-docs {
padding: 7px 20px;
.document {
padding-left: 4rem;
padding-right: 1rem;
//height: 54px;
height: calc(50px + 1.5rem);
&-ico, &-download {
width: 48px;
height: 48px;
}
/* & + .document {
margin-top: 1.5rem;
} */
}
.document-name {
font-weight: normal;
width: 100%;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
}
#content-links {
padding: 0 30px 15px 15px;
> div {
display: flex;
flex-direction: column;
margin-top: 20px;
margin-left: 5px;
padding-bottom: 2px;
//padding-bottom: 10px;
position: relative;
padding-left: 60px;
overflow: hidden;
//min-height: 48px;
min-height: 58px;
.preview {
height: 48px;
width: 48px;
border-radius: 5px;
overflow: hidden;
position: absolute;
left: 0;
top: 0;
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
&.empty {
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
color: #fff;
text-transform: uppercase;
background-color: $blue;
}
}
.url {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
}
.title {
font-size: 16px;
margin-top: 3px;
}
.subtitle {
font-size: 14px;
}
}
#content-audio {
padding: 0 15px 15px 15px;
> div {
margin-top: 15px;
padding-bottom: 10px;
min-height: 60px;
}
}
}
}

34
src/scss/style.scss

@ -29,11 +29,15 @@ $bg: #ffffff;
$text-size: 16px; $text-size: 16px;
$time-size: 12px; $time-size: 12px;
//$large-screen: 1680px;
$large-screen: 16800px;
@import "partials/ico"; @import "partials/ico";
@import "partials/chatlist"; @import "partials/chatlist";
@import "partials/chat"; @import "partials/chat";
@import "partials/sidebar"; @import "partials/sidebar";
@import "partials/leftSidebar"; @import "partials/leftSidebar";
@import "partials/rightSidebar";
@import "partials/mediaViewer"; @import "partials/mediaViewer";
@import "partials/ckin"; @import "partials/ckin";
@import "partials/emojiDropdown"; @import "partials/emojiDropdown";
@ -59,7 +63,18 @@ button, input, optgroup, select, textarea, html {
height: 100vh; height: 100vh;
min-height: 100vh; min-height: 100vh;
width: 100%; width: 100%;
min-width: 100%; //min-width: 100%;
margin: 0 auto;
max-width: $large-screen;
@media (min-width: $large-screen) {
border-top-width: 0;
border-bottom-width: 0;
border-left-width: 1px;
border-right-width: 1px;
border-style: solid;
border-color: #DADCE0;
}
} }
.container { .container {
@ -481,13 +496,13 @@ input {
position: relative; position: relative;
padding-left: 67px; padding-left: 67px;
min-height: 58px; min-height: 58px;
max-width: 286px; max-width: 244px;
overflow: visible!important; overflow: visible!important;
&-toggle, &-download { &-toggle, &-download {
border-radius: 50%; border-radius: 50%;
background-color: $blue; background-color: $blue;
font-size: 2.2rem; font-size: 2.3rem;
align-items: center; align-items: center;
} }
@ -1563,19 +1578,6 @@ div.scrollable::-webkit-scrollbar-thumb {
flex: 1; flex: 1;
} }
.profile-container {
//display: none;
width: 0%;
/* grid-column: 3; */
position: relative;
transition: .2s ease-in-out;
> .scrollable {
min-width: 25vw;
}
}
.preloader { .preloader {
width: 50px; width: 50px;
height: 50px; height: 50px;

4
tsconfig.json

@ -65,9 +65,9 @@
"node_modules", "node_modules",
"public", "public",
"coverage", "coverage",
"./src/lib/StackBlur.js", /* "./src/lib/StackBlur.js",
"./src/lib/*.js", "./src/lib/*.js",
"./src/*.js", "./src/*.js",
"*.js", "*.js", */
] ]
} }

2
webpack.prod.js

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

Loading…
Cancel
Save