Entry.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import EventObject from '../EventObject';
  2. import joinPath from '../joinPath';
  3. import Collection from './Collection';
  4. type EntryArgs = {
  5. directory?: boolean;
  6. fullPath?: string;
  7. title?: string;
  8. modified?: Date;
  9. size?: number;
  10. mimeType?: string;
  11. del?: boolean;
  12. rename?: boolean;
  13. placeholder?: boolean;
  14. collection?: Collection | null;
  15. };
  16. export default class Entry extends EventObject {
  17. #del;
  18. #directory;
  19. #displaySize;
  20. #extension;
  21. #fullPath;
  22. #mimeType;
  23. #modified;
  24. #name;
  25. #path;
  26. #placeholder;
  27. #rename;
  28. #size;
  29. #title;
  30. #type;
  31. collection;
  32. constructor({
  33. directory = false,
  34. fullPath,
  35. title = '',
  36. modified,
  37. size = 0,
  38. mimeType = '',
  39. del = true,
  40. rename = true,
  41. placeholder = false,
  42. collection = null,
  43. }: EntryArgs) {
  44. super();
  45. this.#directory = directory;
  46. this.#fullPath = fullPath;
  47. [this.#path, this.#name] = this.getFilename();
  48. this.#title = title;
  49. this.#modified = modified;
  50. this.#size = size;
  51. this.#mimeType = mimeType;
  52. this.#del = del;
  53. this.#rename = rename;
  54. this.#placeholder = placeholder;
  55. this.collection = collection;
  56. }
  57. createParentEntry() {
  58. return this.update({
  59. fullPath: this.path,
  60. title: '←',
  61. del: false,
  62. rename: false,
  63. });
  64. }
  65. getFilename(path = this.#fullPath) {
  66. path = joinPath(path).split(/\//);
  67. const file = path.pop();
  68. return [joinPath(...path), file];
  69. }
  70. update(properties: EntryArgs = {}) {
  71. return new Entry({
  72. ...{
  73. directory: this.directory,
  74. fullPath: this.fullPath,
  75. modified: this.modified,
  76. size: this.size,
  77. mimeType: this.mimeType,
  78. del: this.del,
  79. rename: this.rename,
  80. collection: this.collection,
  81. },
  82. ...properties,
  83. });
  84. }
  85. get del() {
  86. return this.#del;
  87. }
  88. get directory() {
  89. return this.#directory;
  90. }
  91. get displaySize() {
  92. if (this.directory) {
  93. return '';
  94. }
  95. if (!this.#displaySize) {
  96. this.#displaySize = ['bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'].reduce(
  97. (size, label) =>
  98. typeof size === 'string'
  99. ? size
  100. : size < 1024
  101. ? `${size.toFixed(2 * (label === 'bytes' ? 0 : 1))} ${label}`
  102. : size / 1024,
  103. this.#size
  104. );
  105. }
  106. return this.#displaySize;
  107. }
  108. get extension() {
  109. if (this.directory) {
  110. return '';
  111. }
  112. if (!this.#extension) {
  113. this.#extension = this.name.split('.').pop();
  114. }
  115. return this.#extension;
  116. }
  117. get fullPath() {
  118. return this.#fullPath;
  119. }
  120. get mimeType() {
  121. return this.#mimeType;
  122. }
  123. get modified() {
  124. return this.#modified;
  125. }
  126. get name() {
  127. return this.#name;
  128. }
  129. get path() {
  130. return this.#path;
  131. }
  132. get placeholder() {
  133. return this.#placeholder;
  134. }
  135. set placeholder(value) {
  136. this.#placeholder = value;
  137. this.trigger('entry:update', this);
  138. }
  139. get rename() {
  140. return this.#rename;
  141. }
  142. get size() {
  143. return this.#size;
  144. }
  145. get title() {
  146. if (!this.#title) {
  147. this.#title = decodeURIComponent(this.#name);
  148. }
  149. return this.#title;
  150. }
  151. get type() {
  152. if (!this.#type) {
  153. let type;
  154. const types = {
  155. text: /\.(?:te?xt|i?nfo|php|cgi|faq|ini|htaccess|log|md|sql|sfv|conf|sh|pl|pm|py|rb|(?:s?c|sa)ss|js|java|coffee|[sx]?html?|xml)$/i,
  156. image: /\.(?:jpe?g|gif|a?png|svg)$/i,
  157. video: /\.(?:mp(?:e?g)?4|mov|avi|webm|ogv|mkv)$/i,
  158. audio: /\.(?:mp3|wav|ogg|flac|mka)$/i,
  159. font: /\.(?:woff2?|eot|[ot]tf)$/i,
  160. pdf: /\.pdf/i,
  161. };
  162. for (const [key, value] of Object.entries(types)) {
  163. if (this.name.match(value)) {
  164. return (this.#type = key);
  165. }
  166. }
  167. if (this.#mimeType && (type = this.#mimeType.split('/').shift())) {
  168. return (this.#type = type);
  169. }
  170. this.#type = 'unknown';
  171. }
  172. return this.#type;
  173. }
  174. }