diff --git a/shared/js/ui/channel.ts b/shared/js/channel-tree/channel.ts similarity index 100% rename from shared/js/ui/channel.ts rename to shared/js/channel-tree/channel.ts diff --git a/shared/js/ui/client.ts b/shared/js/channel-tree/client.ts similarity index 100% rename from shared/js/ui/client.ts rename to shared/js/channel-tree/client.ts diff --git a/shared/js/ui/server.ts b/shared/js/channel-tree/server.ts similarity index 100% rename from shared/js/ui/server.ts rename to shared/js/channel-tree/server.ts diff --git a/shared/js/ui/view.ts b/shared/js/channel-tree/view.ts similarity index 100% rename from shared/js/ui/view.ts rename to shared/js/channel-tree/view.ts diff --git a/shared/js/crypto/uid.ts b/shared/js/crypto/uid.ts new file mode 100644 index 00000000..e69de29b diff --git a/shared/js/ui/channel-tree/channel.scss b/shared/js/ui/channel-tree/channel.scss new file mode 100644 index 00000000..e69de29b diff --git a/shared/js/ui/channel-tree/channel.tsx b/shared/js/ui/channel-tree/channel.tsx new file mode 100644 index 00000000..e69de29b diff --git a/shared/js/ui/channel-tree/colors.scss b/shared/js/ui/channel-tree/colors.scss new file mode 100644 index 00000000..e69de29b diff --git a/shared/js/ui/channel-tree/tree.scss b/shared/js/ui/channel-tree/tree.scss new file mode 100644 index 00000000..e69de29b diff --git a/shared/js/ui/channel-tree/tree.tsx b/shared/js/ui/channel-tree/tree.tsx new file mode 100644 index 00000000..e69de29b diff --git a/shared/js/ui/elements/tab.ts b/shared/js/ui/elements/tab.ts deleted file mode 100644 index fb34577c..00000000 --- a/shared/js/ui/elements/tab.ts +++ /dev/null @@ -1,161 +0,0 @@ -/// - -interface JQuery { - asTabWidget(copy?: boolean) : JQuery; - tabify(copy?: boolean) : this; - - changeElementType(type: string) : JQuery; -} - - -if(typeof (customElements) !== "undefined") { - try { - class X_Tab extends HTMLElement {} - class X_Entry extends HTMLElement {} - class X_Tag extends HTMLElement {} - class X_Content extends HTMLElement {} - - customElements.define('x-tab', X_Tab, { extends: 'div' }); - customElements.define('x-entry', X_Entry, { extends: 'div' }); - customElements.define('x-tag', X_Tag, { extends: 'div' }); - customElements.define('x-content', X_Content, { extends: 'div' }); - } catch(error) { - console.warn("failed to define costum elements"); - } -} else { - console.warn(tr("Could not defied tab customElements!")); -} - -var TabFunctions = { - tabify(template: JQuery, copy: boolean = true) : JQuery { - console.log("Tabify: copy=" + copy); - console.log(template); - - let tag = $.spawn("div"); - tag.addClass("tab"); - - let header = $.spawn("div"); - header.addClass("tab-header"); - - let content = $.spawn("div"); - content.addClass("tab-content"); - - content.append($.spawn("div").addClass("height-watcher")); - - let silentContent = $.spawn("div"); - silentContent.addClass("tab-content-invisible"); - - /* add some kind of min height */ - const update_height = () => { - const height_watcher = tag.find("> .tab-content .height-watcher"); - const entries: JQuery = tag.find("> .tab-content-invisible x-content, > .tab-content x-content"); - console.error(entries); - let max_height = 0; - - entries.each((_, _e) => { - const entry = $(_e); - const height = entry.visible_height(); - if(height > max_height) - max_height = height; - }); - - height_watcher.css('min-height', max_height + "px"); - tag.find(".window-resize-listener").trigger('resize'); - }; - - template.find("x-entry").each( (_, _entry) => { - const entry = $(_entry); - - const tag_header = $.spawn("div").addClass("entry"); - const tag_content = copy ? entry.find("x-content").clone(true, true) : entry.find("x-content"); - - { - const header_tag = entry.find("x-tag"); - const header_data = copy ? header_tag.contents().clone(true, true) : header_tag.contents(); - - if(header_tag.attr("x-entry-class")) - tag_header.addClass(header_tag.attr("x-entry-class")); - if(header_tag.attr("x-entry-id")) - tag_header.attr("x-id", header_tag.attr("x-entry-id")); - - tag_header.append(header_data); - - /* listener if the tab might got removed */ - tag_header.addClass("window-resize-listener"); - tag_header.on('resize', event => { - if(!tag_header.is(':visible') && tag_header.hasClass('selected')) { - let element = tag_header.next('.entry:visible'); - if(element.length == 0) - element = tag_header.prev('.entry:visible'); - if(element.length == 0) { - tag_header.removeClass("selected"); - tag_content.hide(); - } else { - element.first().trigger('click'); - } - console.log("Next: %o", tag_header.next('.entry:visible')); - console.log("prev: %o", tag_header.prev('.entry:visible')); - } - }); - } - - content.append(tag_content.hide()); - - tag_header.on("click", () => { - if(tag_header.hasClass("selected")) return; - - tag.find(".tab-header .selected").removeClass("selected"); - tag_header.addClass("selected"); - - content.find("> x-content").hide(); - /* don't show many nodes at once */ - let entries = tag_content.find(".tab-show-partitional"); - entries.hide(); - const show_next = index => { - console.log("Show " + index); - if(index >= entries.length) return; - entries.eq(index).show(); - - setTimeout(show_next.bind(undefined, index + 1), 0); - }; - show_next(0); - - tag_content.trigger('show'); - tag_content.show(); - }); - - console.log(this); - header.append(tag_header); - }); - - setTimeout(() => header.find(".entry").first().trigger("click"), 0); - - tag.append(header); - tag.append(content); - tag.append(silentContent); - - tag.on('tab.resize', update_height); - return tag; - } -}; - -if(!$.fn.asTabWidget) { - $.fn.asTabWidget = function (copy?: boolean) : JQuery { - if($(this).prop("tagName") == "X-TAB") - return TabFunctions.tabify($(this), typeof(copy) === "boolean" ? copy : true); - else { - throw "Invalid tag! " + $(this).prop("tagName"); - } - } -} - -if(!$.fn.tabify) { - $.fn.tabify = function (this: JQuery, copy?: boolean) { - const wrapped_tag = $.spawn("div").append(this); - wrapped_tag.find("x-tab").each((_, _element) => { - const element = $(_element); - element.replaceWith(element.asTabWidget(copy)); - }); - return wrapped_tag.children(); - } -} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 00000000..3a71062c --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,76 @@ +const path = require('path'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + +const isDevelopment = process.env.NODE_ENV === 'development'; +module.exports = { + entry: './src/index.tsx', + devtool: 'inline-source-map', + mode: "development", + plugins: [ + new MiniCssExtractPlugin({ + filename: isDevelopment ? '[name].css' : '[name].[hash].css', + chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css' + }) + ], + module: { + rules: [ + { + test: /\.s[ac]ss$/, + loader: [ + //isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader, + 'style-loader', + { + loader: 'css-loader', + options: { + modules: true, + sourceMap: isDevelopment + } + }, + { + loader: 'sass-loader', + options: { + sourceMap: isDevelopment + } + } + ] + }, + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js', ".scss"], + }, + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist'), + }, + optimization: { + /* + splitChunks: { + chunks: 'async', + minSize: 1, + maxSize: 500000, + minChunks: 1, + maxAsyncRequests: 6, + maxInitialRequests: 4, + automaticNameDelimiter: '~', + automaticNameMaxLength: 30, + cacheGroups: { + defaultVendors: { + test: /[\\/]node_modules[\\/]/, + priority: -10 + }, + default: { + minChunks: 2, + priority: -20, + reuseExistingChunk: true + } + } + } + */ + } +}; \ No newline at end of file