hci-theme 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/entry.jsx ADDED
@@ -0,0 +1,353 @@
1
+ import $ from "jquery";
2
+ import "slick-carousel";
3
+ import ReactDOM from "react-dom";
4
+ import React from "react";
5
+
6
+ // const path = require("path");
7
+ // const YAML = require('yamljs');
8
+ // const widths = YAML.load(path.join(__dirname, "../menu.yml")).widths;
9
+ // console.log(widths);
10
+
11
+ // ////////////////////////////////////////////////////////////////////////////
12
+ // Load scss files (mind ordering)
13
+ // ////////////////////////////////////////////////////////////////////////////
14
+ // import "slick-carousel/slick/slick.scss";
15
+ // import "slick-carousel/slick/slick-theme.scss";
16
+ // import "./scss/_main.scss";
17
+
18
+ // ////////////////////////////////////////////////////////////////////////////
19
+ // Render responsive menu
20
+ // ////////////////////////////////////////////////////////////////////////////
21
+ // import menu from "../menu.js";
22
+
23
+ const Nav = class extends React.Component {
24
+ constructor(props) {
25
+ super(props);
26
+ this.isTouchDevice = "ontouchstart" in window || navigator.maxTouchPoints; // See: https://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript/4819886#4819886
27
+ const getWidth = () => Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
28
+ window.onresize = () => this.setState({ width: getWidth() });
29
+ this.state = {
30
+ activeIndex: undefined,
31
+ width: getWidth(),
32
+ mobileMenuActive: false
33
+ };
34
+ }
35
+
36
+ render() {
37
+ const mobileMenu = (this.isTouchDevice && this.state.width <= 980) || this.state.width <= 980;
38
+ return (
39
+ <nav className={"navigation" + (mobileMenu ? " is-touch" : "")} role="navigation">
40
+ {
41
+ mobileMenu ? (
42
+ <div className="navigation-header-mobile" onClick={() => this.setState({ mobileMenuActive: !this.state.mobileMenuActive })}>
43
+ <i className="icon-menu"></i>
44
+ </div>
45
+ ) : ""
46
+ }
47
+ {
48
+ (!mobileMenu || (mobileMenu && this.state.mobileMenuActive)) ? (
49
+ <div className="navigation-header">
50
+ {
51
+ window.menu.map((item, index) => (
52
+ <div
53
+ onMouseEnter={!mobileMenu ? () => this.setState({ activeIndex: index }) : undefined}
54
+ onMouseLeave={!mobileMenu ? () => this.setState({ activeIndex: undefined }) : undefined}
55
+ key={index}>
56
+ <div className="category-title">
57
+ {
58
+ mobileMenu ? (
59
+ (item.items !== undefined) ? (
60
+ <i className={"toggle-button " + (this.state.activeIndex === index ? "icon-minus-circled" : "icon-plus-circled")} onClick={() => this.setState({ activeIndex: this.state.activeIndex === index ? undefined : index })}></i>
61
+ ) : (
62
+ <span className="toggle-button-placeholder"></span>
63
+ )
64
+ ) : ""
65
+ }
66
+ <a
67
+ href={item.href}
68
+ className={(this.state.activeIndex === index) ? "active" : ""}
69
+ >{item.title}</a>
70
+ </div>
71
+ {
72
+ (item.items !== undefined && (this.state.activeIndex === index)) ? (
73
+ <div className="navigation-submenu">
74
+ {
75
+ item.items.map((subItem, index) => (
76
+ <div className="navigation-submenu-column" key={index}>
77
+ <a className="navigation-submenu-column-header" href={subItem.href}>
78
+ <i className="icon-right-open-top-item"></i>
79
+ {subItem.title}
80
+ </a>
81
+ {
82
+ (subItem.items !== undefined) ? (
83
+ subItem.items.map((subSubItem, index) => (
84
+ <a className="navigation-submenu-column-sub" href={subSubItem.href} key={index}>
85
+ <i className="icon-right-open"></i>
86
+ {subSubItem.title}
87
+ </a>
88
+ ))
89
+ ) : ""
90
+ }
91
+ </div>
92
+ ))
93
+ }
94
+ </div>
95
+ ) : ""
96
+ }
97
+ </div>
98
+ ))
99
+ }
100
+ </div>
101
+ ) : ""
102
+ }
103
+ </nav>
104
+ );
105
+ }
106
+ };
107
+
108
+ ReactDOM.render(<Nav />, document.getElementById("react-placeholder-navigation"));
109
+
110
+ // ////////////////////////////////////////////////////////////////////////////
111
+ // Render breadcrumb navigation
112
+ // ////////////////////////////////////////////////////////////////////////////
113
+ const Breadcrumb = () => {
114
+ const breadcrumbPlaceholder = document.getElementById("react-placeholder-breadcrumb");
115
+ const url = breadcrumbPlaceholder.getAttribute("url").replace(/\/$/, "");
116
+
117
+ const getBreadcrombItems = () => {
118
+ let result = undefined;
119
+
120
+ const home = Object.assign({}, menu[0]);
121
+ home.title = "Home";
122
+
123
+ menu.map(item1 => {
124
+ if (item1.href.replace(/\/$/, "") === url) {
125
+ if (item1 !== menu[0]) {
126
+ result = [home, item1];
127
+ }
128
+ }
129
+ else if (item1.items) {
130
+ item1.items.map(item2 => {
131
+ if (item2.href.replace(/\/$/, "") === url) {
132
+ result = [home, item1, item2];
133
+ }
134
+ else if (item2.items) {
135
+ item2.items.map(item3 => {
136
+ if (item3.href.replace(/\/$/, "") === url) {
137
+ result = [home, item1, item2, item3];
138
+ }
139
+ });
140
+ }
141
+ });
142
+ }
143
+ });
144
+ return result;
145
+ };
146
+
147
+ const items = getBreadcrombItems();
148
+ return (
149
+ <div>
150
+ {
151
+ items ? (
152
+ items.map((item, index) => (
153
+ (index !== items.length - 1) ? (
154
+ <span key={index}><a href={item.href}>{item.title}</a> / </span>
155
+ ) : (
156
+ <span key={index}>{item.title}</span>
157
+ )
158
+ ))
159
+ ) : ""
160
+ }
161
+ </div>
162
+ );
163
+ };
164
+
165
+ ReactDOM.render(<Breadcrumb />, document.getElementById("react-placeholder-breadcrumb"));
166
+
167
+ // ////////////////////////////////////////////////////////////////////////////
168
+ // Render toggle visibility button
169
+ // ////////////////////////////////////////////////////////////////////////////
170
+
171
+ if (document.getElementById("react-placeholder-toggleVisibility") !== null) {
172
+ const ToggleVisibility = class extends React.Component {
173
+ constructor(props) {
174
+ super(props);
175
+ this.state = {
176
+ visible: false,
177
+ language: document.getElementById("react-placeholder-toggleVisibility").getAttribute("language") // null if not set
178
+ };
179
+ }
180
+
181
+ render() {
182
+ console.log(this.state.language);
183
+ const stringShowLess = this.state.language === "DE" ? "Weniger anzeigen" : "Show less";
184
+ const stringShowMore = this.state.language === "DE" ? "Mehr anzeigen" : "Show more";
185
+
186
+ const toggle = () => this.setState({ visible: !this.state.visible },
187
+ (this.state.visible) ? (
188
+ () => $(".toggle-visibility").addClass("hide")
189
+ ) : (
190
+ () => $(".toggle-visibility").removeClass("hide")
191
+ )
192
+ );
193
+
194
+ return (
195
+ <div className="u-cursor-pointer" onClick={toggle}>
196
+ {
197
+ (this.state.visible) ? (
198
+ stringShowLess
199
+ ) : (
200
+ stringShowMore
201
+ )
202
+ }
203
+ </div>
204
+ );
205
+ }
206
+ };
207
+
208
+ ReactDOM.render(<ToggleVisibility />, document.getElementById("react-placeholder-toggleVisibility"));
209
+ }
210
+
211
+ // ////////////////////////////////////////////////////////////////////////////
212
+ // Render filter input
213
+ // ////////////////////////////////////////////////////////////////////////////
214
+
215
+ if (document.getElementById("react-placeholder-filterInput") !== null) {
216
+ const FilterInput = class extends React.Component {
217
+ constructor(props) {
218
+ super(props);
219
+ this.state = {
220
+ visible: false
221
+ };
222
+ }
223
+
224
+ render() {
225
+ // Define case insensitive selector (https://stackoverflow.com/questions/187537/is-there-a-case-insensitive-jquery-contains-selector/187557)
226
+ $.extend($.expr[":"], {
227
+ "containsIN": function (elem, i, match, array) {
228
+ return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
229
+ }
230
+ });
231
+
232
+ const onChange = (event) => {
233
+ const searchString = event.target.value;
234
+ const targetElements = $(".filterInput-targetElement");
235
+ if (searchString == "") {
236
+ targetElements.show();
237
+ }
238
+ else {
239
+ targetElements.hide();
240
+ targetElements.filter(function () {
241
+ return !searchString.split(" ").map(word => $(this).is(":containsIN('" + word + "')")).includes(false);
242
+ }).show();
243
+ }
244
+ };
245
+
246
+ return (
247
+ <div className="filterInput">
248
+ <i className="icon-search"></i>
249
+ <input type="text" onChange={onChange} placeholder="Filter..." />
250
+ </div>
251
+ );
252
+ }
253
+ };
254
+
255
+ ReactDOM.render(<FilterInput />, document.getElementById("react-placeholder-filterInput"));
256
+ }
257
+
258
+ // ////////////////////////////////////////////////////////////////////////////
259
+ // Activate carousel
260
+ // ////////////////////////////////////////////////////////////////////////////
261
+
262
+ $(document).ready(function () {
263
+ $(".slick-element").slick({
264
+ dots: true,
265
+ autoplay: true,
266
+ fade: true,
267
+ autoplaySpeed: 6000,
268
+ speed: 1000
269
+ });
270
+
271
+ $(".slick-element > div").removeClass("hide");
272
+ });
273
+
274
+
275
+ // ////////////////////////////////////////////////////////////////////////////
276
+ // Render bibsonomy
277
+ // ////////////////////////////////////////////////////////////////////////////
278
+ import initBibsonomy from "./bibsonomy.js";
279
+ $(document).ready(function () {
280
+ if ($(".bibsonomy").length) {
281
+ initBibsonomy();
282
+ }
283
+ });
284
+
285
+
286
+ // ////////////////////////////////////////////////////////////////////////////
287
+ // Render topic selector
288
+ // ////////////////////////////////////////////////////////////////////////////
289
+ const element = document.getElementById("react-placeholder-topicSelector");
290
+ if (element !== null) {
291
+ const TopicSelector = class extends React.Component {
292
+ constructor(props) {
293
+ super(props);
294
+ this.typeClasses = [
295
+ "type-mcsp",
296
+ "type-mcst",
297
+ "type-hcip",
298
+ "type-hcit",
299
+ "type-csbt",
300
+ "type-csmp",
301
+ "type-csmt",
302
+ "type-gebt",
303
+ "type-ind",
304
+ "type-indcoop",
305
+ "type-phd"
306
+
307
+ ];
308
+ this.typeStrings = [
309
+ "MCS Bachelor Project",
310
+ "MCS Bachelor Thesis",
311
+ "HCI Master Project",
312
+ "HCI Master Thesis",
313
+ "Computer Science Bachelor Thesis",
314
+ "Computer Science Master Project",
315
+ "Computer Science Master Thesis",
316
+ "Games Engineering Bachelor Thesis",
317
+ "Industry Project",
318
+ "Industry Cooperation",
319
+ "PhD Project"
320
+ ];
321
+ this.state = {
322
+ selected: 0
323
+ };
324
+ }
325
+
326
+ updateTopics() {
327
+ if (this.state.selected !== 0) {
328
+ $(".topic." + this.typeClasses[this.state.selected - 1]).show();
329
+ $(".topic:not(." + this.typeClasses[this.state.selected - 1] + ")").hide();
330
+ }
331
+ else {
332
+ $(".topic").show();
333
+ }
334
+ }
335
+
336
+ render() {
337
+ return (
338
+ <div className="column-layout">
339
+ {
340
+ ["Show all"].concat(this.typeStrings).map((string, index) => (
341
+ <div key={index}>
342
+ <input type="radio" value={index} checked={this.state.selected === index} onChange={() => this.setState({ selected: index }, this.updateTopics)} />
343
+ {string}
344
+ </div>
345
+ ))
346
+ }
347
+ </div>
348
+ );
349
+ }
350
+ };
351
+
352
+ ReactDOM.render(<TopicSelector />, document.getElementById("react-placeholder-topicSelector"));
353
+ }
data/extconf.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'fileutils'
2
+ require 'mkmf'
3
+
4
+ print "Installing HCI-Theme"
5
+
6
+ system "npm install"
7
+ system "npx webpack -p --config webpack.config.js --mode=production"
8
+ FileUtils.copy_entry "node_modules/slick-carousel", "_sass/slick-carousel"
9
+ FileUtils.copy_entry "node_modules/slick-carousel/slick/fonts/slick.woff", "assets/css/fonts/slick.woff"
10
+ FileUtils.copy_entry "node_modules/slick-carousel/slick/fonts/slick.ttf", "assets/css/fonts/slick.ttf"
11
+ FileUtils.copy_entry "node_modules/slick-carousel/slick/ajax-loader.gif", "assets/css/ajax-loader.gif"
12
+
13
+ create_makefile ''
data/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "devDependencies": {
3
+ "@babel/core": "^7.7.4",
4
+ "@babel/preset-env": "^7.7.4",
5
+ "@babel/preset-react": "^7.7.4",
6
+ "babel-loader": "^8.0.6",
7
+ "css-loader": "^3.2.0",
8
+ "file-loader": "^5.0.2",
9
+ "gulp": "^4.0.2",
10
+ "jquery": "^3.4.1",
11
+ "mini-css-extract-plugin": "^0.8.0",
12
+ "node-sass": "^4.13.0",
13
+ "react": "^16.12.0",
14
+ "react-dom": "^16.12.0",
15
+ "sass-loader": "^8.0.0",
16
+ "sharp": "^0.23.3",
17
+ "slick-carousel": "^1.8.1",
18
+ "style-loader": "^1.0.0",
19
+ "url-loader": "^3.0.0",
20
+ "watch": "^1.0.2",
21
+ "webpack": "^4.41.2",
22
+ "webpack-cli": "^3.3.10",
23
+ "yamljs": "^0.3.0",
24
+ "yml-loader": "^2.1.0"
25
+ },
26
+ "dependencies": {}
27
+ }
data/webpack.config.js ADDED
@@ -0,0 +1,52 @@
1
+ // ////////////////////////////////////////////////////////////////////////////
2
+ // Run webpack
3
+ // ////////////////////////////////////////////////////////////////////////////
4
+ const path = require("path");
5
+ const ExtractTextPlugin = require("mini-css-extract-plugin");
6
+
7
+ module.exports = {
8
+ context: __dirname,
9
+ entry: path.join(__dirname, "entry.jsx"),
10
+ output: {
11
+ path: path.join(__dirname, "assets"),
12
+ filename: "bundle.js"
13
+ },
14
+ module: {
15
+ rules: [{
16
+ test: /.jsx?$/,
17
+ include: [__dirname, __dirname + "/../"],
18
+ use: {
19
+ loader: 'babel-loader',
20
+ options: {
21
+ presets: ['@babel/preset-env', '@babel/preset-react']
22
+ }
23
+ }
24
+ },
25
+ {
26
+ test: /\.scss$/,
27
+ use: [{
28
+ loader: ExtractTextPlugin.loader,
29
+ },
30
+ "css-loader",
31
+ "sass-loader"
32
+ ]
33
+ },
34
+ {
35
+ test: /\.(woff|woff2|eot|ttf)$/,
36
+ loader: 'url-loader?limit=100000'
37
+ },
38
+ {
39
+ test: /\.(svg|gif)$/,
40
+ loader: "file-loader"
41
+ }
42
+ ]
43
+ },
44
+ plugins: [
45
+ new ExtractTextPlugin({
46
+ filename: 'style.css'
47
+ }),
48
+ ],
49
+ node: {
50
+ fs: "empty"
51
+ }
52
+ };
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hci-theme
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Jan-Philipp Stauffert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-12-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jekyll-sass-converter
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.16'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.16'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '12.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '12.0'
69
+ description:
70
+ email:
71
+ - jan-philipp.stauffert@uni-wuerzburg.de
72
+ executables: []
73
+ extensions:
74
+ - extconf.rb
75
+ extra_rdoc_files: []
76
+ files:
77
+ - _includes/block
78
+ - _includes/faq
79
+ - _includes/footer
80
+ - _includes/image
81
+ - _includes/youtube
82
+ - _layouts/base.html
83
+ - _layouts/post.html
84
+ - _layouts/text.html
85
+ - _sass/_base.scss
86
+ - _sass/_bibsonomy.scss
87
+ - _sass/_constants.scss
88
+ - _sass/_icons.scss
89
+ - _sass/_main.scss
90
+ - _sass/_utilities.scss
91
+ - bibsonomy.js
92
+ - entry.jsx
93
+ - extconf.rb
94
+ - package.json
95
+ - webpack.config.js
96
+ homepage: https://gitlab2.informatik.uni-wuerzburg.de/hci-development/hci-theme
97
+ licenses:
98
+ - Apache-2.0
99
+ metadata: {}
100
+ post_install_message: HCI-Theme installed!
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '2.6'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubygems_version: 3.0.6
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: The HCI page theme.
119
+ test_files: []