From 45844990194710f8c3ed6adaedf0e346e87f0d53 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 28 Jan 2019 16:26:39 +0200 Subject: [PATCH] Added A way to get Game-icons.net icons into the database (it's not secure yet), plus some icon ui --- app/.meteor/packages | 1 - app/.meteor/versions | 1 - app/imports/api/icons/Icons.js | 50 +++++++++++ app/imports/server/publications/icons.js | 26 ++++++ app/imports/server/publications/index.js | 11 +-- app/imports/ui/StoryBook.vue | 3 + .../ui/components/IconSearch.Story.vue | 16 ++++ app/imports/ui/components/IconSearch.vue | 76 +++++++++++++++++ app/imports/ui/icons/IconAdmin.vue | 83 +++++++++++++++++++ app/imports/ui/icons/importIcons.js | 31 +++++++ app/imports/ui/router.js | 5 ++ app/package-lock.json | 5 ++ app/package.json | 1 + 13 files changed, 302 insertions(+), 7 deletions(-) create mode 100644 app/imports/api/icons/Icons.js create mode 100644 app/imports/server/publications/icons.js create mode 100644 app/imports/ui/components/IconSearch.Story.vue create mode 100644 app/imports/ui/components/IconSearch.vue create mode 100644 app/imports/ui/icons/IconAdmin.vue create mode 100644 app/imports/ui/icons/importIcons.js diff --git a/app/.meteor/packages b/app/.meteor/packages index 21c346df..ef2e1a5b 100644 --- a/app/.meteor/packages +++ b/app/.meteor/packages @@ -51,4 +51,3 @@ static-html aldeed:collection2@3.0.0 aldeed:schema-index akryum:vue-component -autopublish@1.0.7 diff --git a/app/.meteor/versions b/app/.meteor/versions index 0037252f..17878f35 100644 --- a/app/.meteor/versions +++ b/app/.meteor/versions @@ -12,7 +12,6 @@ akryum:vue-router2@0.2.2 aldeed:collection2@3.0.1 aldeed:schema-index@3.0.0 allow-deny@1.1.0 -autopublish@1.0.7 autoupdate@1.5.0 babel-compiler@7.2.4 babel-runtime@1.3.0 diff --git a/app/imports/api/icons/Icons.js b/app/imports/api/icons/Icons.js new file mode 100644 index 00000000..5d21b44c --- /dev/null +++ b/app/imports/api/icons/Icons.js @@ -0,0 +1,50 @@ +import SimpleSchema from 'simpl-schema'; + +let Icons = new Mongo.Collection('icons'); + +iconsSchema = new SimpleSchema({ + name: { + type: String, + unique: true, + index: 1, + }, + description: { + type: String, + optional: true, + }, + tags: { + type: Array, + optional: true, + index: 1, + }, + 'tags.$': { + type: String, + }, + shape: { + type: String, + }, +}); + +if (Meteor.isServer) { + Icons._ensureIndex({ + 'name': 'text', + 'description': 'text', + 'tags': 'text', + }); +} + +Icons.attachSchema(iconsSchema); + +const writeIcons = new ValidatedMethod({ + name: 'writeIcons', + validate: null, + run(icons){ + if (Meteor.isServer){ + this.unblock(); + Icons.rawCollection().insert(icons, {ordered: false}); + } + } +}); + +export { writeIcons }; +export default Icons; diff --git a/app/imports/server/publications/icons.js b/app/imports/server/publications/icons.js new file mode 100644 index 00000000..49f13418 --- /dev/null +++ b/app/imports/server/publications/icons.js @@ -0,0 +1,26 @@ +import Icons from '/imports/api/icons/Icons.js'; + +Meteor.publish("sampleIcons", function(){ + return Icons.find({}, {limit: 50}); +}); + + +Meteor.publish("searchIcons", function(searchValue) { + // Don't publish anything if there's no search value + if (!searchValue) { + return []; + } + return Icons.find( + { $text: {$search: searchValue} }, + { + // relevant documents have a higher score. + fields: { + score: { $meta: "textScore" } + }, + // `score` property specified in the projection fields above. + sort: { + score: { $meta: "textScore" } + } + } + ); +}); diff --git a/app/imports/server/publications/index.js b/app/imports/server/publications/index.js index e0e0d145..4271f09f 100644 --- a/app/imports/server/publications/index.js +++ b/app/imports/server/publications/index.js @@ -1,5 +1,6 @@ -import "./characterList.js"; -import "./library.js"; -import "./singleCharacter.js"; -import "./user.js"; -import "./users.js"; +import './characterList.js'; +import './library.js'; +import './singleCharacter.js'; +import './user.js'; +import './users.js'; +import './icons.js'; diff --git a/app/imports/ui/StoryBook.vue b/app/imports/ui/StoryBook.vue index a253731e..52763670 100644 --- a/app/imports/ui/StoryBook.vue +++ b/app/imports/ui/StoryBook.vue @@ -44,8 +44,10 @@ import DialogStack from '/imports/ui/dialogStack/DialogStack.Story.vue'; import HealthBar from '/imports/ui/components/HealthBar.Story.vue'; import HitDiceListTile from '/imports/ui/components/HitDiceListTile.Story.vue'; + import IconSearch from '/imports/ui/components/IconSearch.Story.vue'; import SkillListTile from '/imports/ui/components/SkillListTile.Story.vue'; import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue'; + export default { components: { AbilityListTile, @@ -54,6 +56,7 @@ DialogStack, HealthBar, HitDiceListTile, + IconSearch, SkillListTile, ToolbarLayout, }, diff --git a/app/imports/ui/components/IconSearch.Story.vue b/app/imports/ui/components/IconSearch.Story.vue new file mode 100644 index 00000000..f3393267 --- /dev/null +++ b/app/imports/ui/components/IconSearch.Story.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/app/imports/ui/components/IconSearch.vue b/app/imports/ui/components/IconSearch.vue new file mode 100644 index 00000000..dd0e517e --- /dev/null +++ b/app/imports/ui/components/IconSearch.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/app/imports/ui/icons/IconAdmin.vue b/app/imports/ui/icons/IconAdmin.vue new file mode 100644 index 00000000..84d07d9d --- /dev/null +++ b/app/imports/ui/icons/IconAdmin.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/app/imports/ui/icons/importIcons.js b/app/imports/ui/icons/importIcons.js new file mode 100644 index 00000000..ae814f12 --- /dev/null +++ b/app/imports/ui/icons/importIcons.js @@ -0,0 +1,31 @@ +import { writeIcons } from '/imports/api/icons/Icons.js'; + +/* + * Import a SVG sprite file. All the icons must contain one id and one path with a + * single 'd' attribute. + * + * A svg sprite file can be created by downloading the entire archive of + * https://game-icons.net/ then using the search function with *.svg to copy + * all the individual files into a single directory, and then using the npm + * sprite-generator to run `svg-sprite-generate -d icons -o sprite.svg` to save + * the sprite file. +*/ + +export default function importIcons(file){ + let id, d, icons = []; + let reader = new FileReader(); + + reader.onload = function(){ + reader.result.match(/i?d="([^"])+"/gi).forEach(s => { + if (s[0] === 'i'){ + id = s.slice(4, -1); + } else if (s[0] === 'd'){ + d = s.slice(3, -1); + icons.push ({_id: Random.id(), name: id, shape: d}); + } + }); + writeIcons.call(icons); + }; + + reader.readAsText(file); +}; diff --git a/app/imports/ui/router.js b/app/imports/ui/router.js index 82dd19a7..682978ce 100644 --- a/app/imports/ui/router.js +++ b/app/imports/ui/router.js @@ -49,6 +49,7 @@ RouterFactory.configure(factory => { //Development routes if (Meteor.isDevelopment){ let StoryBook = require('/imports/ui/StoryBook.vue').default; + let IconAdmin = require('/imports/ui/icons/IconAdmin.vue').default; factory.addRoutes([ { path: '/storybook/:component', @@ -58,6 +59,10 @@ RouterFactory.configure(factory => { path: '/storybook', name: 'storybook', component: StoryBook, + }, { + path: '/icon-admin', + name: "iconAdmin", + component: IconAdmin, }, ]); } diff --git a/app/package-lock.json b/app/package-lock.json index 6c9fe581..c0c92620 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -2149,6 +2149,11 @@ "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-1.4.2.tgz", "integrity": "sha512-HnMBBtO5FqTPzr6FXVlxnYulGMrHVlcmBL7SSLE/AQnNbdUpT6Jw9D/Kdw9fbK5mdn7JSWMcfWpPJUrqYTtK1w==" }, + "vuetify-upload-button": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/vuetify-upload-button/-/vuetify-upload-button-1.2.2.tgz", + "integrity": "sha512-WQmAevQl4F2musSLpPzyT3fCBCksFiL7V6Jh8qD1fxGxHjAvjGywJKWjPLMzXDHkJfo6q2OPJtynPU0QXN5hGA==" + }, "vuex": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.0.1.tgz", diff --git a/app/package.json b/app/package.json index a98ee859..9801f6ca 100644 --- a/app/package.json +++ b/app/package.json @@ -29,6 +29,7 @@ "vue-meteor-tracker": "^2.0.0-beta.5", "vue-router": "^3.0.2", "vuetify": "^1.4.2", + "vuetify-upload-button": "^1.2.2", "vuex": "^3.0.1" }, "devDependencies": {}