iconly 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +76 -0
  4. data/Rakefile +33 -0
  5. data/app/assets/config/iconly_manifest.js +2 -0
  6. data/app/assets/images/iconly/Noto-Sans-700.eot +0 -0
  7. data/app/assets/images/iconly/Noto-Sans-700.svg +336 -0
  8. data/app/assets/images/iconly/Noto-Sans-700.ttf +0 -0
  9. data/app/assets/images/iconly/Noto-Sans-700.woff +0 -0
  10. data/app/assets/images/iconly/Noto-Sans-700.woff2 +0 -0
  11. data/app/assets/images/iconly/Noto-Sans-regular.eot +0 -0
  12. data/app/assets/images/iconly/Noto-Sans-regular.svg +335 -0
  13. data/app/assets/images/iconly/Noto-Sans-regular.ttf +0 -0
  14. data/app/assets/images/iconly/Noto-Sans-regular.woff +0 -0
  15. data/app/assets/images/iconly/Noto-Sans-regular.woff2 +0 -0
  16. data/app/assets/images/iconly/Source-Sans-Pro-600.eot +0 -0
  17. data/app/assets/images/iconly/Source-Sans-Pro-600.svg +339 -0
  18. data/app/assets/images/iconly/Source-Sans-Pro-600.ttf +0 -0
  19. data/app/assets/images/iconly/Source-Sans-Pro-600.woff +0 -0
  20. data/app/assets/images/iconly/Source-Sans-Pro-600.woff2 +0 -0
  21. data/app/assets/images/iconly/Source-Sans-Pro-regular.eot +0 -0
  22. data/app/assets/images/iconly/Source-Sans-Pro-regular.svg +345 -0
  23. data/app/assets/images/iconly/Source-Sans-Pro-regular.ttf +0 -0
  24. data/app/assets/images/iconly/Source-Sans-Pro-regular.woff +0 -0
  25. data/app/assets/images/iconly/Source-Sans-Pro-regular.woff2 +0 -0
  26. data/app/assets/images/iconly/favicon.png +0 -0
  27. data/app/assets/images/iconly/iconly.eot +0 -0
  28. data/app/assets/images/iconly/iconly.svg +157 -0
  29. data/app/assets/images/iconly/iconly.ttf +0 -0
  30. data/app/assets/images/iconly/iconly.woff +0 -0
  31. data/app/assets/javascripts/iconly/application.js +24 -0
  32. data/app/assets/javascripts/iconly/iconly.coffee +5 -0
  33. data/app/assets/javascripts/iconly/jquery.sticky.js +268 -0
  34. data/app/assets/javascripts/iconly/package.coffee +25 -0
  35. data/app/assets/javascripts/iconly/project.coffee +68 -0
  36. data/app/assets/javascripts/iconly/scroller.coffee +17 -0
  37. data/app/assets/stylesheets/iconly/application.scss +21 -0
  38. data/app/assets/stylesheets/iconly/buttons.scss +314 -0
  39. data/app/assets/stylesheets/iconly/file_input.scss +25 -0
  40. data/app/assets/stylesheets/iconly/header.scss +179 -0
  41. data/app/assets/stylesheets/iconly/iconly.scss.erb +61 -0
  42. data/app/assets/stylesheets/iconly/layout.scss +269 -0
  43. data/app/assets/stylesheets/iconly/overrides.scss +58 -0
  44. data/app/assets/stylesheets/iconly/typography.scss.erb +48 -0
  45. data/app/controllers/iconly/application_controller.rb +8 -0
  46. data/app/controllers/iconly/packages_controller.rb +54 -0
  47. data/app/controllers/iconly/project_icons_controller.rb +24 -0
  48. data/app/controllers/iconly/projects_controller.rb +67 -0
  49. data/app/helpers/iconly/application_helper.rb +35 -0
  50. data/app/helpers/iconly/packages_helper.rb +29 -0
  51. data/app/helpers/iconly/project_icons_helper.rb +4 -0
  52. data/app/helpers/iconly/projects_helper.rb +4 -0
  53. data/app/helpers/iconly/sessions_helper.rb +43 -0
  54. data/app/jobs/iconly/application_job.rb +4 -0
  55. data/app/mailers/iconly/application_mailer.rb +6 -0
  56. data/app/models/iconly/application_record.rb +5 -0
  57. data/app/models/iconly/icon.rb +44 -0
  58. data/app/models/iconly/package.rb +5 -0
  59. data/app/models/iconly/project.rb +5 -0
  60. data/app/models/iconly/project/downloader.rb +50 -0
  61. data/app/models/iconly/project/font_generator.rb +65 -0
  62. data/app/models/iconly/project_icon.rb +23 -0
  63. data/app/models/iconly/user.rb +5 -0
  64. data/app/uploaders/iconly/svg_uploader.rb +51 -0
  65. data/app/views/iconly/packages/_form.html.erb +48 -0
  66. data/app/views/iconly/packages/new.html.erb +5 -0
  67. data/app/views/iconly/projects/_form.html.erb +25 -0
  68. data/app/views/iconly/projects/_packages.html.erb +91 -0
  69. data/app/views/iconly/projects/edit.html.erb +5 -0
  70. data/app/views/iconly/projects/index.html.erb +37 -0
  71. data/app/views/iconly/projects/new.html.erb +5 -0
  72. data/app/views/iconly/projects/show.html.erb +53 -0
  73. data/app/views/layouts/iconly/_footer.html.erb +18 -0
  74. data/app/views/layouts/iconly/_header.html.erb +89 -0
  75. data/app/views/layouts/iconly/application.html.erb +29 -0
  76. data/config/fontcustom/fontcustom_manifest.yml +53 -0
  77. data/config/fontcustom/templates/iconly.css +28 -0
  78. data/config/routes.rb +13 -0
  79. data/db/migrate/20170130210746_enable_uuid_extension.rb +5 -0
  80. data/db/migrate/20170130211049_create_iconly_users.rb +9 -0
  81. data/db/migrate/20170130220400_create_iconly_packages.rb +12 -0
  82. data/db/migrate/20170131002414_create_iconly_icons.rb +13 -0
  83. data/db/migrate/20170131081131_create_iconly_projects.rb +11 -0
  84. data/db/migrate/20170131084626_create_iconly_project_icons.rb +10 -0
  85. data/db/migrate/20170203144731_add_icon_count_to_packages.rb +5 -0
  86. data/lib/iconly.rb +22 -0
  87. data/lib/iconly/concerns/models/package.rb +41 -0
  88. data/lib/iconly/concerns/models/project.rb +27 -0
  89. data/lib/iconly/concerns/models/user.rb +23 -0
  90. data/lib/iconly/engine.rb +5 -0
  91. data/lib/iconly/version.rb +3 -0
  92. data/lib/iconly/zip_file_generator.rb +58 -0
  93. data/lib/tasks/iconly_tasks.rake +4 -0
  94. metadata +374 -0
@@ -0,0 +1,5 @@
1
+ module Iconly
2
+ class Package < ApplicationRecord
3
+ include Concerns::Models::Package
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Iconly
2
+ class Project < ApplicationRecord
3
+ include Concerns::Models::Project
4
+ end
5
+ end
@@ -0,0 +1,50 @@
1
+ module Iconly
2
+ class Project
3
+ class Downloader
4
+ def initialize(project)
5
+ @project = project
6
+ end
7
+
8
+ def call
9
+ return unless @project.icons.any?
10
+ generate
11
+ zip_file_path
12
+ rescue => e
13
+ Rails.logger.error e
14
+ nil
15
+ end
16
+
17
+ private
18
+
19
+ def generate
20
+ with_glyphs do |path|
21
+ Project::FontGenerator.new(path, output_path).call
22
+ end
23
+ ZipFileGenerator.new(output_path, zip_file_path).write
24
+ end
25
+
26
+ def with_glyphs
27
+ Dir.mktmpdir do |dir|
28
+ FileUtils.cp @project.icons.map(&:svg_path), dir
29
+ yield dir if block_given?
30
+ end
31
+ end
32
+
33
+ def output_path
34
+ @output_path ||= Dir.mktmpdir
35
+ end
36
+
37
+ def svg_path
38
+ unless @svg_path
39
+ icon = @project.icons.first
40
+ @svg_path = File.dirname(Rails.root.join("public#{icon.svg.url}"))
41
+ end
42
+ @svg_path
43
+ end
44
+
45
+ def zip_file_path
46
+ @zip_file_path ||= File.join(Iconly.downloads_folder, "#{@project.slug}_#{Time.current.to_i}.zip")
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,65 @@
1
+ module Iconly
2
+ class Project
3
+ class FontGenerator
4
+ include FileUtils::Verbose
5
+
6
+ FONT_NAME = 'iconly'.freeze
7
+
8
+ def initialize(vectors_path, output_path, font_name = nil)
9
+ @vectors_path = vectors_path
10
+ @output_path = output_path
11
+ @font_name = font_name || FONT_NAME
12
+ end
13
+
14
+ def call
15
+ input = {
16
+ vectors: @vectors_path,
17
+ templates: templates_path
18
+ }
19
+
20
+ raw_options = {
21
+ debug: Rails.env.development?,
22
+ input: input,
23
+ templates: %w(iconly.css),
24
+ font_name: @font_name,
25
+ css_selector: ".#{@font_name}-{{glyph}}",
26
+ no_hash: true,
27
+ verbose: true,
28
+ manifest: manifest_path,
29
+ output: {
30
+ fonts: output_fonts_path,
31
+ css: @output_path
32
+ }
33
+ }
34
+
35
+ run_generators raw_options
36
+ end
37
+
38
+ private
39
+
40
+ def run_generators(raw_options)
41
+ options = Fontcustom::Options.new(raw_options).options
42
+ manifest = Fontcustom::Manifest.new(manifest_path, options)
43
+
44
+ Fontcustom::Generator::Font.new(manifest.manifest).generate
45
+ Fontcustom::Generator::Template.new(manifest.manifest).generate
46
+ end
47
+
48
+ def output_fonts_path
49
+ File.join(@output_path, 'fonts')
50
+ end
51
+
52
+ def manifest_path
53
+ File.join(config_folder, 'fontcustom_manifest.yml')
54
+ end
55
+
56
+ def templates_path
57
+ File.join(config_folder, 'templates')
58
+ end
59
+
60
+ def config_folder
61
+ File.expand_path('../../../../../config/fontcustom', __FILE__)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,23 @@
1
+ module Iconly
2
+ class ProjectIcon < ApplicationRecord
3
+ belongs_to :project, class_name: 'Project'
4
+ belongs_to :icon, class_name: 'Icon'
5
+
6
+ def self.all_projects(user_id, term = nil)
7
+ user_projects = Project.owned_by(user_id)
8
+ icons = includes(:icon, :project)
9
+ .joins(:icon, :project)
10
+ .merge(user_projects)
11
+ icons = icons.merge(Icon.search(term)) if term.present?
12
+ project_icons = icons
13
+ .order('iconly_projects.name')
14
+ .group_by(&:project)
15
+
16
+ if term.blank?
17
+ projects_without_icons = user_projects.without_icons
18
+ projects_without_icons.each { |p| project_icons[p] = [] }
19
+ end
20
+ project_icons
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ module Iconly
2
+ class User < ApplicationRecord
3
+ include Concerns::Models::User
4
+ end
5
+ end
@@ -0,0 +1,51 @@
1
+ module Iconly
2
+ class SvgUploader < CarrierWave::Uploader::Base
3
+ CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
4
+
5
+ # Include RMagick or MiniMagick support:
6
+ # include CarrierWave::RMagick
7
+ # include CarrierWave::MiniMagick
8
+
9
+ # Choose what kind of storage to use for this uploader:
10
+ storage :file
11
+ # storage :fog
12
+
13
+ # Override the directory where uploaded files will be stored.
14
+ # This is a sensible default for uploaders that are meant to be mounted:
15
+ def store_dir
16
+ "uploads/packages/#{model.package.to_param}/icons"
17
+ end
18
+
19
+ # Provide a default URL as a default if there hasn't been a file uploaded:
20
+ # def default_url
21
+ # # For Rails 3.1+ asset pipeline compatibility:
22
+ # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
23
+ #
24
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
25
+ # end
26
+
27
+ # Process files as they are uploaded:
28
+ # process scale: [200, 300]
29
+ #
30
+ # def scale(width, height)
31
+ # # do something
32
+ # end
33
+
34
+ # Create different versions of your uploaded files:
35
+ # version :thumb do
36
+ # process resize_to_fit: [50, 50]
37
+ # end
38
+
39
+ # Add a white list of extensions which are allowed to be uploaded.
40
+ # For images you might use something like this:
41
+ def extension_whitelist
42
+ %w(svg)
43
+ end
44
+
45
+ # Override the filename of the uploaded files:
46
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
47
+ # def filename
48
+ # "something.jpg" if original_filename
49
+ # end
50
+ end
51
+ end
@@ -0,0 +1,48 @@
1
+ <div class="row">
2
+ <div class="col-md-6">
3
+ <%= form_for package, html: { multipart: true } do |f| %>
4
+ <% if package.errors.any? %>
5
+ <div class="alert alert-danger">
6
+ <ul>
7
+ <% package.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="form-group">
15
+ <%= f.label :name %>
16
+ <%= f.text_field :name, class: 'form-control', placeholder: 'Choose a name' %>
17
+ </div>
18
+
19
+ <div class="form-group">
20
+ <%= f.label :icon_files, 'Icons' %>
21
+ <div class="card">
22
+ <div class="card-block text-center pt-4 pb-4">
23
+ <div class="package-files">
24
+ <div class="in" id="package-files">No files selected</div>
25
+ </div>
26
+ <button class="btn btn-smt btn-custom btn-white btn-file">
27
+ Add files ...
28
+ <%= f.file_field :icon_files, type: :file, multiple: true, class: 'form-control' %>
29
+ </button>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="actions mt-5">
35
+ <%= f.submit 'Save', class: 'btn btn-success' %> &nbsp;or
36
+ <%= link_to 'Cancel', path_after_create_package, class: 'text-danger' %>
37
+ </div>
38
+ <% end %>
39
+ </div>
40
+ </div>
41
+
42
+ <% content_for :script do %>
43
+ <script>
44
+ $(function() {
45
+ iconly.Package.start('#package_icon_files', '#package-files');
46
+ });
47
+ </script>
48
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <%= title 'Add Icons' %>
2
+
3
+ <h1 class="page-header">Add icons</h1>
4
+
5
+ <%= render 'form', package: @package %>
@@ -0,0 +1,25 @@
1
+ <div class="row">
2
+ <div class="col-sm-6">
3
+ <%= form_for project do |f| %>
4
+ <% if project.errors.any? %>
5
+ <div class="alert alert-danger">
6
+ <ul>
7
+ <% project.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="form-group">
15
+ <%= f.label :name %>
16
+ <%= f.text_field :name, class: 'form-control', placeholder: 'Choose a name' %>
17
+ </div>
18
+
19
+ <div class="actions mt-5">
20
+ <%= f.submit 'Save', class: 'btn btn-success' %> &nbsp;or
21
+ <%= link_to 'Cancel', cancel_path, class: 'text-danger' %>
22
+ </div>
23
+ <% end %>
24
+ </div>
25
+ </div>
@@ -0,0 +1,91 @@
1
+ <div class="row">
2
+ <div class="col-md-2 hidden-sm-down">
3
+ <div class="sidebar" id="sticky-packages">
4
+ <h4 class="text-pale brd-btm">
5
+ Packages
6
+ <span class="badge badge-pale float-right"><%= packages.size %></span>
7
+ </h4>
8
+
9
+ <table>
10
+ <% packages.each do |package, _| %>
11
+ <tr>
12
+ <td>
13
+ <%= link_to package.name, "##{package.to_param}", 'data-scroll-to' => package.to_param, class: 'text-pale text-bold' %>
14
+ </td>
15
+ <td class="text-right">
16
+ <span class="badge badge-pale"><%= package.icon_count %></span>
17
+ </td>
18
+ </tr>
19
+ <% end %>
20
+ </table>
21
+ </div>
22
+ </div>
23
+
24
+ <div class="col-md-8 col-sm-12 project-pkg-<%= project.present? %>">
25
+ <% packages.each do |package, icons| %>
26
+
27
+ <div class="row">
28
+ <div class="col-md-8">
29
+ <h3 class="font-bold" id="<%= package.to_param %>"><%= package.name %></h3>
30
+ </div>
31
+ <div class="col-md-4 text-right inline-links">
32
+ <% if my_package?(package) %>
33
+ <%= link_to_share package %>
34
+
35
+ <%= link_to package_path(package),
36
+ method: :delete,
37
+ class: 'text-danger mt-05 list-inline-item text-sm',
38
+ title: 'Delete package',
39
+ data: { confirm: 'You sure you want to delete this package?', toggle: 'iconly-tooltip' } do %>
40
+ <span class="iconly-trash text-pale"></span>
41
+ <% end %>
42
+ <% end %>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="card mb-4">
47
+ <div class="card-block">
48
+ <% icons.each do |icon| %>
49
+ <%= icon_svg icon, project_icons %>
50
+ <% end %>
51
+ </div>
52
+ </div>
53
+ <% end %>
54
+
55
+ <% if packages.blank? %>
56
+ <div class="jumbotron text-center">
57
+ <i class="iconly-baby2 mr-05 font-lg"></i>
58
+ <h3 class="mb-4">Can't find that icon ...</h3>
59
+ <%= link_to 'Clear search', project_path(project), class: 'btn btn-lg btn-primary' %>
60
+ </div>
61
+ <% end %>
62
+ </div>
63
+
64
+ <div class="col-md-2 hidden-sm-down project-pkg-true">
65
+ <div id="sticky-project-icons">
66
+ <h4 class="text-pale brd-btm">
67
+ Project Icons
68
+ <span class="badge badge-pale float-right" id="project-icons-count"><%= project.icons.size %></span>
69
+ </h4>
70
+ <div id="project-icons">
71
+ <% project.icons.each do |icon| %>
72
+ <div class="btn btn-svg btn-sm float-left remove" title="Remove from project" data-action="remove-from-project" data-id="<%= icon.id %>">
73
+ <%= icon.markup %>
74
+ <i class="iconly-cross bg-danger text-white rm"></i>
75
+ </div>
76
+ <% end %>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </div> <!-- end row -->
81
+
82
+ <%= content_for :script do %>
83
+ <script>
84
+ $(function() {
85
+ var options = { topSpacing: 70 };
86
+ $('#sticky-packages').sticky(options);
87
+ $('#sticky-project-icons').sticky(options);
88
+ new iconly.Scroller(options)
89
+ });
90
+ </script>
91
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <%= title 'Editing Project' %>
2
+
3
+ <h1 class="page-header">Editing Project</h1>
4
+
5
+ <%= render 'form', project: @project, cancel_path: project_path(@project) %>
@@ -0,0 +1,37 @@
1
+ <%= title 'Projects' %>
2
+
3
+ <h1 class="page-header">Projects</h1>
4
+
5
+ <% @projects.each do |project, project_icons| %>
6
+
7
+ <h3 class="font-bold text-dark"><%= link_to project.name, project_path(project) %></h3>
8
+ <div class="card mb-4">
9
+ <div class="card-block">
10
+ <% project_icons.each do |project_icon| %>
11
+ <div class="btn btn-svg float-left" title="<%= project_icon.icon.name %>">
12
+ <%= project_icon.icon.contents.html_safe %>
13
+ </div>
14
+ <% end %>
15
+
16
+ <% if project_icons.blank? %>
17
+ <div class="text-pale">No icons added yet.</div>
18
+ <% end %>
19
+ </div>
20
+ </div>
21
+
22
+ <% end %>
23
+
24
+ <% if @projects.blank? %>
25
+ <div class="jumbotron text-center">
26
+ <i class="iconly-baby2 mr-05 font-lg"></i>
27
+ <% if params[:q].present? %>
28
+ <h3 class="mb-4">Can't find that icon ...</h3>
29
+ <%= link_to 'Clear search', projects_path, class: 'btn btn-lg btn-primary' %>
30
+ <% else %>
31
+ <h3>No projects created yet</h3>
32
+ <hr/>
33
+ <p>No worries, there's still time.</p>
34
+ <%= link_to 'Start now', new_project_path, class: 'btn btn-lg btn-primary' %>
35
+ <% end %>
36
+ </div>
37
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <%= title 'Projects' %>
2
+
3
+ <h1 class="page-header">New Project</h1>
4
+
5
+ <%= render 'form', project: @project, cancel_path: projects_path %>
@@ -0,0 +1,53 @@
1
+ <%= title @project.name %>
2
+
3
+ <div class="row page-header">
4
+ <div class="col-sm-6">
5
+ <h1><%= @project.name %></h1>
6
+ </div>
7
+ <div class="col-sm-6 text-right">
8
+ <a class="dropdown-toggle m-a-0 btn btn-default" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
9
+ <i class="iconly-menu"></i>
10
+ </a>
11
+
12
+ <div class="dropdown-menu dropdown-menu-right">
13
+ <%= link_to edit_project_path(@project), class: 'dropdown-item' do %>
14
+ <i class="iconly-pencil mr-05 text-info"></i>
15
+ Edit Project
16
+ <% end %>
17
+ <%= link_to project_path(@project),
18
+ method: :delete,
19
+ data: { confirm: 'Are you sure you want to delete this project?' },
20
+ class: 'dropdown-item' do %>
21
+ <i class="iconly-trash mr-05 text-danger"></i>
22
+ Delete Project
23
+ <% end %>
24
+
25
+ <div class="dropdown-divider"></div>
26
+
27
+ <%= link_to generate_font_project_path(@project), class: 'dropdown-item', data: { method: :post } do %>
28
+ <i class="iconly-folder-download text-primary mr-05"></i>
29
+ Generate Font
30
+ <% end %>
31
+
32
+ <div class="dropdown-divider"></div>
33
+
34
+ <%= link_to new_project_path, class: 'dropdown-item' do %>
35
+ <i class="iconly-file-add mr-05 text-info"></i>
36
+ New Project
37
+ <% end %>
38
+ </div>
39
+ </div>
40
+ </div>
41
+
42
+ <%= render partial: 'packages', locals: {
43
+ packages: @packages,
44
+ project: @project,
45
+ project_icons: @project.project_icons.map(&:icon_id) } %>
46
+
47
+ <%= content_for :script do %>
48
+ <script>
49
+ $(function() {
50
+ iconly.Project.start('<%= @project.id %>', '<%= project_icons_path %>');
51
+ });
52
+ </script>
53
+ <% end %>