iconly 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +76 -0
- data/Rakefile +33 -0
- data/app/assets/config/iconly_manifest.js +2 -0
- data/app/assets/images/iconly/Noto-Sans-700.eot +0 -0
- data/app/assets/images/iconly/Noto-Sans-700.svg +336 -0
- data/app/assets/images/iconly/Noto-Sans-700.ttf +0 -0
- data/app/assets/images/iconly/Noto-Sans-700.woff +0 -0
- data/app/assets/images/iconly/Noto-Sans-700.woff2 +0 -0
- data/app/assets/images/iconly/Noto-Sans-regular.eot +0 -0
- data/app/assets/images/iconly/Noto-Sans-regular.svg +335 -0
- data/app/assets/images/iconly/Noto-Sans-regular.ttf +0 -0
- data/app/assets/images/iconly/Noto-Sans-regular.woff +0 -0
- data/app/assets/images/iconly/Noto-Sans-regular.woff2 +0 -0
- data/app/assets/images/iconly/Source-Sans-Pro-600.eot +0 -0
- data/app/assets/images/iconly/Source-Sans-Pro-600.svg +339 -0
- data/app/assets/images/iconly/Source-Sans-Pro-600.ttf +0 -0
- data/app/assets/images/iconly/Source-Sans-Pro-600.woff +0 -0
- data/app/assets/images/iconly/Source-Sans-Pro-600.woff2 +0 -0
- data/app/assets/images/iconly/Source-Sans-Pro-regular.eot +0 -0
- data/app/assets/images/iconly/Source-Sans-Pro-regular.svg +345 -0
- data/app/assets/images/iconly/Source-Sans-Pro-regular.ttf +0 -0
- data/app/assets/images/iconly/Source-Sans-Pro-regular.woff +0 -0
- data/app/assets/images/iconly/Source-Sans-Pro-regular.woff2 +0 -0
- data/app/assets/images/iconly/favicon.png +0 -0
- data/app/assets/images/iconly/iconly.eot +0 -0
- data/app/assets/images/iconly/iconly.svg +157 -0
- data/app/assets/images/iconly/iconly.ttf +0 -0
- data/app/assets/images/iconly/iconly.woff +0 -0
- data/app/assets/javascripts/iconly/application.js +24 -0
- data/app/assets/javascripts/iconly/iconly.coffee +5 -0
- data/app/assets/javascripts/iconly/jquery.sticky.js +268 -0
- data/app/assets/javascripts/iconly/package.coffee +25 -0
- data/app/assets/javascripts/iconly/project.coffee +68 -0
- data/app/assets/javascripts/iconly/scroller.coffee +17 -0
- data/app/assets/stylesheets/iconly/application.scss +21 -0
- data/app/assets/stylesheets/iconly/buttons.scss +314 -0
- data/app/assets/stylesheets/iconly/file_input.scss +25 -0
- data/app/assets/stylesheets/iconly/header.scss +179 -0
- data/app/assets/stylesheets/iconly/iconly.scss.erb +61 -0
- data/app/assets/stylesheets/iconly/layout.scss +269 -0
- data/app/assets/stylesheets/iconly/overrides.scss +58 -0
- data/app/assets/stylesheets/iconly/typography.scss.erb +48 -0
- data/app/controllers/iconly/application_controller.rb +8 -0
- data/app/controllers/iconly/packages_controller.rb +54 -0
- data/app/controllers/iconly/project_icons_controller.rb +24 -0
- data/app/controllers/iconly/projects_controller.rb +67 -0
- data/app/helpers/iconly/application_helper.rb +35 -0
- data/app/helpers/iconly/packages_helper.rb +29 -0
- data/app/helpers/iconly/project_icons_helper.rb +4 -0
- data/app/helpers/iconly/projects_helper.rb +4 -0
- data/app/helpers/iconly/sessions_helper.rb +43 -0
- data/app/jobs/iconly/application_job.rb +4 -0
- data/app/mailers/iconly/application_mailer.rb +6 -0
- data/app/models/iconly/application_record.rb +5 -0
- data/app/models/iconly/icon.rb +44 -0
- data/app/models/iconly/package.rb +5 -0
- data/app/models/iconly/project.rb +5 -0
- data/app/models/iconly/project/downloader.rb +50 -0
- data/app/models/iconly/project/font_generator.rb +65 -0
- data/app/models/iconly/project_icon.rb +23 -0
- data/app/models/iconly/user.rb +5 -0
- data/app/uploaders/iconly/svg_uploader.rb +51 -0
- data/app/views/iconly/packages/_form.html.erb +48 -0
- data/app/views/iconly/packages/new.html.erb +5 -0
- data/app/views/iconly/projects/_form.html.erb +25 -0
- data/app/views/iconly/projects/_packages.html.erb +91 -0
- data/app/views/iconly/projects/edit.html.erb +5 -0
- data/app/views/iconly/projects/index.html.erb +37 -0
- data/app/views/iconly/projects/new.html.erb +5 -0
- data/app/views/iconly/projects/show.html.erb +53 -0
- data/app/views/layouts/iconly/_footer.html.erb +18 -0
- data/app/views/layouts/iconly/_header.html.erb +89 -0
- data/app/views/layouts/iconly/application.html.erb +29 -0
- data/config/fontcustom/fontcustom_manifest.yml +53 -0
- data/config/fontcustom/templates/iconly.css +28 -0
- data/config/routes.rb +13 -0
- data/db/migrate/20170130210746_enable_uuid_extension.rb +5 -0
- data/db/migrate/20170130211049_create_iconly_users.rb +9 -0
- data/db/migrate/20170130220400_create_iconly_packages.rb +12 -0
- data/db/migrate/20170131002414_create_iconly_icons.rb +13 -0
- data/db/migrate/20170131081131_create_iconly_projects.rb +11 -0
- data/db/migrate/20170131084626_create_iconly_project_icons.rb +10 -0
- data/db/migrate/20170203144731_add_icon_count_to_packages.rb +5 -0
- data/lib/iconly.rb +22 -0
- data/lib/iconly/concerns/models/package.rb +41 -0
- data/lib/iconly/concerns/models/project.rb +27 -0
- data/lib/iconly/concerns/models/user.rb +23 -0
- data/lib/iconly/engine.rb +5 -0
- data/lib/iconly/version.rb +3 -0
- data/lib/iconly/zip_file_generator.rb +58 -0
- data/lib/tasks/iconly_tasks.rake +4 -0
- 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,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, '×'.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,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,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
|