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,58 @@
1
+ a:hover {
2
+ text-decoration: none;
3
+ }
4
+
5
+ .dropdown-menu,
6
+ .form-control,
7
+ .btn {
8
+ font-size: inherit;
9
+ }
10
+
11
+ .btn {
12
+ border-radius: 3px;
13
+ }
14
+
15
+ .alert-danger ul {
16
+ margin-bottom: 0;
17
+ }
18
+
19
+ .btn-default,
20
+ .btn-default:hover,
21
+ .btn-default:focus,
22
+ .btn-default:active,
23
+ .btn-default.active,
24
+ .btn-default.focus,
25
+ .btn-default:active,
26
+ .btn-default:focus,
27
+ .btn-default:hover,
28
+ .open > .dropdown-toggle.btn-default {
29
+ background-color: #5fbeaa !important;
30
+ border: 1px solid #5fbeaa !important;
31
+ color: #fff;
32
+ }
33
+
34
+ .text-default {
35
+ color: #5fbeaa;
36
+ }
37
+
38
+ .badge-pale {
39
+ background-color: $color-pale;
40
+ }
41
+
42
+ .alert-danger ul {
43
+ padding-left: 1rem;
44
+ }
45
+
46
+ .field_with_errors {
47
+ label {
48
+ color: #f99;
49
+ }
50
+
51
+ .form-control {
52
+ border: 1px solid #ebcccc;
53
+ }
54
+ }
55
+
56
+ .jumbotron {
57
+ background-color: #fbfbfb;
58
+ }
@@ -0,0 +1,48 @@
1
+ @font-face {
2
+ font-family: 'Noto Sans';
3
+ font-weight: 400;
4
+ font-style: normal;
5
+ src: url(<%= asset_path 'iconly/Noto-Sans-regular.eot' %>);
6
+ src: url(<%= asset_path 'iconly/Noto-Sans-regular.eot?#iefix' %>) format('embedded-opentype'),
7
+ url(<%= asset_path 'iconly/Noto-Sans-regular.woff2' %>) format('woff2'),
8
+ url(<%= asset_path 'iconly/Noto-Sans-regular.woff' %>) format('woff'),
9
+ url(<%= asset_path 'iconly/Noto-Sans-regular.ttf' %>) format('truetype'),
10
+ url(<%= asset_path 'iconly/Noto-Sans-regular.svg#NotoSans' %>) format('svg');
11
+ }
12
+
13
+ @font-face {
14
+ font-family: 'Noto Sans';
15
+ font-weight: 700;
16
+ font-style: normal;
17
+ src: url(<%= asset_path 'iconly/Noto-Sans-700.eot' %>);
18
+ src: url(<%= asset_path 'iconly/Noto-Sans-700.eot?#iefix' %>) format('embedded-opentype'),
19
+ url(<%= asset_path 'iconly/Noto-Sans-700.woff2' %>) format('woff2'),
20
+ url(<%= asset_path 'iconly/Noto-Sans-700.woff' %>) format('woff'),
21
+ url(<%= asset_path 'iconly/Noto-Sans-700.ttf' %>) format('truetype'),
22
+ url(<%= asset_path 'iconly/Noto-Sans-700.svg#NotoSans' %>) format('svg');
23
+ }
24
+
25
+ @font-face {
26
+ font-family: 'Source Sans Pro';
27
+ font-weight: 400;
28
+ font-style: normal;
29
+ src: url(<%= asset_path 'iconly/Source-Sans-Pro-regular.eot' %>);
30
+ src: url(<%= asset_path 'iconly/Source-Sans-Pro-regular.eot?#iefix' %>) format('embedded-opentype'),
31
+ url(<%= asset_path 'iconly/Source-Sans-Pro-regular.woff2' %>) format('woff2'),
32
+ url(<%= asset_path 'iconly/Source-Sans-Pro-regular.woff' %>) format('woff'),
33
+ url(<%= asset_path 'iconly/Source-Sans-Pro-regular.ttf' %>) format('truetype'),
34
+ url(<%= asset_path 'iconly/Source-Sans-Pro-regular.svg#SourceSansPro' %>) format('svg');
35
+ }
36
+
37
+ @font-face {
38
+ font-family: 'Source Sans Pro';
39
+ font-weight: 600;
40
+ font-style: normal;
41
+ src: url(<%= asset_path 'iconly/Source-Sans-Pro-600.eot' %>);
42
+ src: url(<%= asset_path 'iconly/Source-Sans-Pro-600.eot?#iefix' %>) format('embedded-opentype'),
43
+ url(<%= asset_path 'iconly/Source-Sans-Pro-600.woff2' %>) format('woff2'),
44
+ url(<%= asset_path 'iconly/Source-Sans-Pro-600.woff' %>) format('woff'),
45
+ url(<%= asset_path 'iconly/Source-Sans-Pro-600.ttf' %>) format('truetype'),
46
+ url(<%= asset_path 'iconly/Source-Sans-Pro-600.svg#SourceSansPro' %>) format('svg');
47
+ }
48
+
@@ -0,0 +1,8 @@
1
+ module Iconly
2
+ class ApplicationController < ActionController::Base
3
+ include SessionsHelper
4
+
5
+ protect_from_forgery with: :exception
6
+ before_action :require_sign_in
7
+ end
8
+ end
@@ -0,0 +1,54 @@
1
+ require_dependency 'iconly/application_controller'
2
+
3
+ module Iconly
4
+ class PackagesController < ApplicationController
5
+ before_action :set_package, only: %i(share destroy)
6
+
7
+ helper_method :path_after_create_package
8
+
9
+ def new
10
+ store_path_after_create_package
11
+ @package = Package.new
12
+ end
13
+
14
+ def create
15
+ @package = current_user.packages.build(package_params)
16
+ @package.icon_files_required = true
17
+
18
+ if @package.save
19
+ redirect_to path_after_create_package,
20
+ notice: '<i class="iconly-baby mr-05"></i> Great, more new shiny icons in the bag!'
21
+ else
22
+ render :new
23
+ end
24
+ end
25
+
26
+ def share
27
+ @package.update!(shared: !@package.shared?)
28
+ end
29
+
30
+ def destroy
31
+ @package.destroy
32
+ redirect_to (request.referer || projects_path), notice: '<i class="iconly-baby mr-05"></i> Package is now gone'
33
+ end
34
+
35
+ private
36
+
37
+ def set_package
38
+ @package = current_user.packages.friendly.find(params[:id])
39
+ end
40
+
41
+ def package_params
42
+ params.require(:package).permit(:name, icon_files: [])
43
+ end
44
+
45
+ def store_path_after_create_package
46
+ session.delete(:path_after_create_package) if session[:path_after_create_package]
47
+ session[:path_after_create_package] = request.referer if request.referer.present?
48
+ end
49
+
50
+ def path_after_create_package
51
+ session[:path_after_create_package] || projects_path
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,24 @@
1
+ require_dependency 'iconly/application_controller'
2
+
3
+ module Iconly
4
+ class ProjectIconsController < ApplicationController
5
+ before_action :set_project
6
+
7
+ def create
8
+ @project.project_icons.create(icon_id: params[:icon_id])
9
+ head :no_content
10
+ end
11
+
12
+ def destroy
13
+ project_icon = @project.project_icons.find_by(icon_id: params[:id])
14
+ project_icon.destroy if project_icon
15
+ head :no_content
16
+ end
17
+
18
+ private
19
+
20
+ def set_project
21
+ @project = current_user.projects.friendly.find(params[:project_id])
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,67 @@
1
+ require_dependency 'iconly/application_controller'
2
+
3
+ module Iconly
4
+ class ProjectsController < ApplicationController
5
+ before_action :set_project, only: [:show, :edit, :update, :destroy, :generate_font]
6
+
7
+ def index
8
+ @projects = ProjectIcon.all_projects(current_user.id, params[:q])
9
+ end
10
+
11
+ def show
12
+ @packages = Icon.all_packages(current_user.id, params[:q])
13
+ end
14
+
15
+ def new
16
+ @project = Project.new
17
+ end
18
+
19
+ def edit
20
+ end
21
+
22
+ def create
23
+ @project = current_user.projects.build(project_params)
24
+
25
+ if @project.save
26
+ redirect_to project_path(@project),
27
+ notice: '<i class="iconly-baby mr-05"></i> Great, a new project was created!'
28
+ else
29
+ render :new
30
+ end
31
+ end
32
+
33
+ def update
34
+ if @project.update(project_params)
35
+ redirect_to project_path(@project),
36
+ notice: '<i class="iconly-baby mr-05"></i> Awsome, project updated all right!'
37
+ else
38
+ render :edit
39
+ end
40
+ end
41
+
42
+ def generate_font
43
+ if (zip_file = Project::Downloader.new(@project).call)
44
+ send_file zip_file
45
+ else
46
+ flash[:error] = '<i class="iconly-baby2 mr-05"></i> '\
47
+ 'Sorry an error occurred generating the font, please try again.'
48
+ redirect_to project_path(@project)
49
+ end
50
+ end
51
+
52
+ def destroy
53
+ @project.destroy
54
+ redirect_to projects_url, notice: '<i class="iconly-baby mr-05"></i> Project is gone to the bin.'
55
+ end
56
+
57
+ private
58
+
59
+ def set_project
60
+ @project = current_user.projects.friendly.find(params[:id])
61
+ end
62
+
63
+ def project_params
64
+ params.require(:project).permit(:name)
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,35 @@
1
+ module Iconly
2
+ module ApplicationHelper
3
+ def title(content)
4
+ content_for :title do
5
+ content
6
+ end
7
+ end
8
+
9
+ def render_flash
10
+ content_tag :div, class: 'container flash-container' do
11
+ flash.each do |name, msg|
12
+ div = content_tag :div, class: alert_class_name(name) do
13
+ btn = content_tag :button, type: 'button', class: 'close', 'data-dismiss' => 'alert' do
14
+ content_tag :span, '&times;'.html_safe
15
+ end
16
+ concat btn
17
+ concat sanitize(msg)
18
+ end
19
+ concat div
20
+ end
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def alert_class_name(flash_name)
27
+ class_name = case flash_name
28
+ when 'notice' then 'success'
29
+ when 'error' then 'danger'
30
+ else flash_name
31
+ end
32
+ "alert alert-#{class_name} mb-4"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,29 @@
1
+ module Iconly
2
+ module PackagesHelper
3
+ def my_package?(package)
4
+ current_user && package.user == current_user
5
+ end
6
+
7
+ def link_to_share(package)
8
+ classes = %w(iconly-earth text-sm mr-1)
9
+ classes << 'shared' if package.shared?
10
+ link_to(share_package_path(package),
11
+ class: classes.join(' '),
12
+ title: 'Make public',
13
+ data: { action: 'share-package', toggle: 'iconly-tooltip' }) do
14
+ content_tag :span, '', class: 'text-pale'
15
+ end
16
+ end
17
+
18
+ def icon_svg(icon, project_icons = nil)
19
+ css_class = %w(btn btn-svg float-left)
20
+ css_class << 'selected' if project_icons && project_icons.include?(icon.id)
21
+ data = {
22
+ id: icon.id,
23
+ action: 'add-to-project',
24
+ toggle: 'iconly-tooltip'
25
+ }
26
+ content_tag :div, icon.markup, class: css_class.join(' '), data: data, title: icon.human_name
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ module Iconly
2
+ module ProjectIconsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Iconly
2
+ module ProjectsHelper
3
+ end
4
+ end
@@ -0,0 +1,43 @@
1
+ module Iconly
2
+ module SessionsHelper
3
+ protected
4
+
5
+ def logout_path
6
+ Iconly.logout_path
7
+ end
8
+
9
+ def login_path
10
+ Iconly.login_path
11
+ end
12
+
13
+ def current_user
14
+ unless @current_user
15
+ if (user_id = session[:user_id] || cookies.signed[:user_id])
16
+ @current_user = Iconly::User.find_by(id: user_id)
17
+ end
18
+ end
19
+ @current_user
20
+ end
21
+
22
+ def sign_in(user_id)
23
+ session[:user_id] = user_id
24
+ cookies.signed[:user_id] = user_id
25
+ end
26
+
27
+ def sign_out
28
+ session.delete(:user_id)
29
+ cookies.signed[:user_id] = nil
30
+ end
31
+
32
+ def signed_in?
33
+ current_user.present?
34
+ end
35
+
36
+ def require_sign_in
37
+ return if signed_in?
38
+ session[:redirect_after_login] = request.original_fullpath
39
+ flash[:danger] = 'You need to be signed in to access this page.'
40
+ redirect_to root_path
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,4 @@
1
+ module Iconly
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Iconly
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Iconly
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,44 @@
1
+ module Iconly
2
+ class Icon < ApplicationRecord
3
+ belongs_to :package, class_name: 'Package'
4
+ has_many :project_icons, dependent: :destroy
5
+
6
+ mount_uploader :svg, SvgUploader
7
+
8
+ extend FriendlyId
9
+ friendly_id :name, use: [:slugged, :scoped], scope: :package
10
+
11
+ validates :name, :contents, presence: true
12
+
13
+ scope :search, ->(term) { where('iconly_icons.name ILIKE ?', "%#{term}%") }
14
+
15
+ def self.all_packages(user_id, term = nil)
16
+ with_package = user_id ? Package.shared_or_owned_by(user_id) : Package.shared
17
+ icons = includes(:package)
18
+ .joins(:package)
19
+ .merge(with_package)
20
+ icons = icons.merge(search(term)) if term.present?
21
+ icons
22
+ .order('iconly_packages.name')
23
+ .group_by(&:package)
24
+ end
25
+
26
+ def svg_path
27
+ File.join(Iconly.svg_folder, svg.try(:url) || '')
28
+ end
29
+
30
+ def markup
31
+ (contents || '').gsub(']>', '').html_safe
32
+ end
33
+
34
+ def human_name
35
+ name.humanize(capitalize: false)
36
+ end
37
+
38
+ private
39
+
40
+ def should_generate_new_friendly_id?
41
+ name_changed?
42
+ end
43
+ end
44
+ end