frameit 2.8.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5d29de960084e2ece56a732f13b8ec0d8a1833a
4
- data.tar.gz: bbdf114d3489c4c8d908fff8501a7e1a43343c70
3
+ metadata.gz: 5f153eb5635aba47fe4f2404223b06181bf98fd2
4
+ data.tar.gz: 48ef840b23d480681a43a256503c146f3bd8d928
5
5
  SHA512:
6
- metadata.gz: f425e0880bd3e12085471ebc0caef3ccbe3b56c3dbe890c790b73c4e8afc6e22eeaa87ea27423a705fcb817930cd899f1b221f1590d6139e041bba9e41440e18
7
- data.tar.gz: c39aac2349ea4f6685fe759864d42083b88a3f51a0a6ba942a72f99d5104b54bab2a9b2b752192bd878fa47d92ab0942be5c2cda675585badbecc34113eb5f6c
6
+ metadata.gz: 736c49029deb88bdee79e932d4e1d0e807d1d89f1b461e5419dc3d3cd1bd9c050000f5844171c65e46fe5aa4a17bc2da078b7b022252abb65ee5a531bc5f9e76
7
+ data.tar.gz: 604c1f3b9918d28788ccefb101208a37973461ee447655dc8e8cdef716628da338a2b21b678566d869f6142c112aa052c93866279a81208d1447307153fd3b71
data/README.md CHANGED
@@ -32,7 +32,6 @@ frameit
32
32
  [![Twitter: @KauseFx](https://img.shields.io/badge/contact-@FastlaneTools-blue.svg?style=flat)](https://twitter.com/FastlaneTools)
33
33
  [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/fastlane/fastlane/blob/master/frameit/LICENSE)
34
34
  [![Gem](https://img.shields.io/gem/v/frameit.svg?style=flat)](http://rubygems.org/gems/frameit)
35
- [![Build Status](https://img.shields.io/circleci/project/fastlane/fastlane/master.svg?style=flat)](https://circleci.com/gh/fastlane/fastlane)
36
35
 
37
36
  ###### Quickly put your screenshots into the right device frames
38
37
 
@@ -52,7 +51,7 @@ Get in contact with the developer on Twitter: [@FastlaneTools](https://twitter.c
52
51
  </p>
53
52
 
54
53
  -------
55
- <h5 align="center"><code>frameit</code> is part of <a href="https://fastlane.tools">fastlane</a>: The easiest way to automate building and releasing your iOS and Android apps.</h5>
54
+ <h5 align="center"><code>frameit</code> is part of <a href="https://fastlane.tools">fastlane</a>: The easiest way to automate beta deployments and releases for your iOS and Android apps.</h5>
56
55
 
57
56
 
58
57
  # Features
@@ -116,9 +115,9 @@ To use the silver version of the frames:
116
115
 
117
116
  frameit silver
118
117
 
119
- To run the setup process again to add new frames use:
118
+ To download the latest frames
120
119
 
121
- frameit setup
120
+ frameit download_frames
122
121
 
123
122
  When using `frameit` without titles on top, the screenshots will have the full resolution, which means they can't be uploaded to the App Store directly. They are supposed to be used for websites, print media and emails. Check out the section below to use the screenshots for the App Store.
124
123
 
@@ -134,6 +133,7 @@ Use it to define the general information:
134
133
 
135
134
  ```json
136
135
  {
136
+ "device_frame_version": "latest",
137
137
  "default": {
138
138
  "keyword": {
139
139
  "font": "./fonts/MyFont-Rg.otf"
@@ -235,7 +235,7 @@ Check out the [MindNode example project](https://github.com/fastlane/examples/tr
235
235
 
236
236
  ## [`fastlane`](https://fastlane.tools) Toolchain
237
237
 
238
- - [`fastlane`](https://fastlane.tools): The easiest way to automate building and releasing your iOS and Android apps
238
+ - [`fastlane`](https://fastlane.tools): The easiest way to automate beta deployments and releases for your iOS and Android apps
239
239
  - [`deliver`](https://github.com/fastlane/fastlane/tree/master/deliver): Upload screenshots, metadata and your app to the App Store
240
240
  - [`snapshot`](https://github.com/fastlane/fastlane/tree/master/snapshot): Automate taking localized screenshots of your iOS app on every device
241
241
  - [`pem`](https://github.com/fastlane/fastlane/tree/master/pem): Automatically generate and renew your push notification profiles
@@ -1,6 +1,6 @@
1
1
  require 'mini_magick'
2
2
  require 'frameit/version'
3
- require 'frameit/frame_converter'
3
+ require 'frameit/frame_downloader'
4
4
  require 'frameit/device_types'
5
5
  require 'frameit/runner'
6
6
  require 'frameit/screenshot'
@@ -23,6 +23,24 @@ module Frameit
23
23
  Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
24
24
  UI = FastlaneCore::UI
25
25
  ROOT = Pathname.new(File.expand_path('../..', __FILE__))
26
+
27
+ # Defaults to latest, might be a time stamp if defined in the Framefile.json
28
+ def self.frames_version
29
+ return @frames_version if @frames_version
30
+ @frames_version = "latest"
31
+
32
+ config_files = Dir["./**/Framefile.json"]
33
+ if config_files.count > 0
34
+ config = ConfigParser.new.load(config_files.first)
35
+ if config.data["device_frame_version"].to_s.length > 0
36
+ @frames_version = config.data["device_frame_version"]
37
+ end
38
+ end
39
+
40
+ UI.success("Using device frames version '#{@frames_version}'")
41
+
42
+ return @frames_version
43
+ end
26
44
  end
27
45
 
28
46
  # rubocop:disable all
@@ -29,7 +29,7 @@ module Frameit
29
29
 
30
30
  command :run do |c|
31
31
  c.syntax = 'frameit black'
32
- c.description = "Adds a black frame around all screenshots."
32
+ c.description = "Adds a black frame around all screenshots"
33
33
 
34
34
  c.action do |args, options|
35
35
  load_config(options)
@@ -39,7 +39,7 @@ module Frameit
39
39
 
40
40
  command :silver do |c|
41
41
  c.syntax = 'frameit silver'
42
- c.description = "Adds a silver frame around all screenshots."
42
+ c.description = "Adds a silver frame around all screenshots"
43
43
 
44
44
  c.action do |args, options|
45
45
  load_config(options)
@@ -47,12 +47,41 @@ module Frameit
47
47
  end
48
48
  end
49
49
 
50
+ command :gold do |c|
51
+ c.syntax = 'frameit gold'
52
+ c.description = "Adds a gold frame around all screenshots"
53
+
54
+ c.action do |args, options|
55
+ load_config(options)
56
+ Frameit::Runner.new.run('.', Frameit::Color::GOLD)
57
+ end
58
+ end
59
+
60
+ command :rose_gold do |c|
61
+ c.syntax = 'frameit rose_gold'
62
+ c.description = "Adds a rose gold frame around all screenshots"
63
+
64
+ c.action do |args, options|
65
+ load_config(options)
66
+ Frameit::Runner.new.run('.', Frameit::Color::ROSE_GOLD)
67
+ end
68
+ end
69
+
50
70
  command :setup do |c|
51
71
  c.syntax = 'frameit setup'
52
- c.description = "Helps you adding new frames."
72
+ c.description = "Downloads and sets up the latest device frames"
73
+
74
+ c.action do |args, options|
75
+ Frameit::FrameDownloader.new.download_frames
76
+ end
77
+ end
78
+
79
+ command :download_frames do |c|
80
+ c.syntax = 'frameit download_frames'
81
+ c.description = "Downloads and sets up the latest device frames"
53
82
 
54
83
  c.action do |args, options|
55
- Frameit::FrameConverter.new.run
84
+ Frameit::FrameDownloader.new.download_frames
56
85
  end
57
86
  end
58
87
 
@@ -1,5 +1,7 @@
1
1
  module Frameit
2
2
  class ConfigParser
3
+ attr_reader :data
4
+
3
5
  def load(path)
4
6
  return nil unless File.exist?(path) # we are okay with no config at all
5
7
  UI.verbose("Parsing config file '#{path}'")
@@ -1,11 +1,13 @@
1
1
  module Frameit
2
2
  module Color
3
- BLACK = "SpaceGray"
4
- SILVER = "Slvr"
3
+ BLACK = "Space Gray"
4
+ SILVER = "Silver"
5
+ ROSE_GOLD = "Rose Gold"
6
+ GOLD = "Gold"
5
7
  end
6
8
 
7
9
  module Orientation
8
- PORTRAIT = "Vert"
9
- LANDSCAPE = "Horz"
10
+ PORTRAIT = "PORTRAIT"
11
+ LANDSCAPE = "LANDSCAPE"
10
12
  end
11
13
  end
@@ -9,8 +9,13 @@ module Frameit
9
9
  self.screenshot = screenshot
10
10
  prepare_image
11
11
 
12
- if load_frame # e.g. Mac doesn't need a frame
12
+ if load_frame # Mac doesn't need a frame
13
13
  self.frame = MiniMagick::Image.open(load_frame)
14
+ self.frame.rotate(90) unless self.screenshot.portrait? # we use portrait device frames for landscape screenshots
15
+ elsif self.class == Editor
16
+ # Couldn't find device frame (probably an iPhone 4, for which there are no images available any more)
17
+ # Message is already shown elsewhere
18
+ return
14
19
  end
15
20
 
16
21
  if should_add_title?
@@ -37,17 +42,31 @@ module Frameit
37
42
 
38
43
  def store_result
39
44
  output_path = screenshot.path.gsub('.png', '_framed.png').gsub('.PNG', '_framed.png')
40
- image.format "png"
41
- image.write output_path
45
+ image.format("png")
46
+ image.write(output_path)
42
47
  UI.success "Added frame: '#{File.expand_path(output_path)}'"
43
48
  end
44
49
 
45
50
  # puts the screenshot into the frame
46
51
  def put_into_frame
52
+ # We have to rotate the screenshot, since the offset information is for portrait
53
+ # only. Instead of doing the calculations ourselves, it's much easier to let
54
+ # imagemagick do the hard lifting for landscape screenshots
55
+ unless self.screenshot.portrait?
56
+ frame.rotate(-90)
57
+ @image.rotate(-90)
58
+ end
59
+
47
60
  @image = frame.composite(image, "png") do |c|
48
61
  c.compose "Over"
49
62
  c.geometry offset['offset']
50
63
  end
64
+
65
+ # We have to revert the state to be landscape screenshots
66
+ unless self.screenshot.portrait?
67
+ frame.rotate(90)
68
+ @image.rotate(90)
69
+ end
51
70
  end
52
71
 
53
72
  def offset
@@ -89,11 +108,11 @@ module Frameit
89
108
 
90
109
  if self.frame # we have no frame on le mac
91
110
  resize_frame!
92
- @image = put_into_frame
111
+ put_into_frame
93
112
 
94
113
  # Decrease the size of the framed screenshot to fit into the defined padding + background
95
114
  frame_width = background.width - horizontal_frame_padding * 2
96
- image.resize "#{frame_width}x"
115
+ @image.resize "#{frame_width}x"
97
116
  end
98
117
 
99
118
  self.top_space_above_device = vertical_frame_padding
@@ -160,7 +179,9 @@ module Frameit
160
179
 
161
180
  # Resize the frame as it's too low quality by default
162
181
  def resize_frame!
163
- multiplicator = (screenshot.size[0].to_f / offset['width'].to_f) # by how much do we have to change this?
182
+ screenshot_width = self.screenshot.portrait? ? screenshot.size[0] : screenshot.size[1]
183
+
184
+ multiplicator = (screenshot_width.to_f / offset['width'].to_f) # by how much do we have to change this?
164
185
  new_frame_width = multiplicator * frame.width # the new width for the frame
165
186
  frame.resize "#{new_frame_width.round}x" # resize it to the calculated witdth
166
187
  modify_offset(multiplicator) # modify the offset to properly insert the screenshot into the frame later
@@ -271,7 +292,7 @@ module Frameit
271
292
  return @config if @config
272
293
 
273
294
  config_path = File.join(File.expand_path("..", screenshot.path), "Framefile.json")
274
- config_path = File.join(File.expand_path("../..", screenshot.path), "Framefile.json") unless File.exist? config_path
295
+ config_path = File.join(File.expand_path("../..", screenshot.path), "Framefile.json") unless File.exist?(config_path)
275
296
  file = ConfigParser.new.load(config_path)
276
297
  return {} unless file # no config file at all
277
298
  @config = file.fetch_value(screenshot.path)
@@ -0,0 +1,71 @@
1
+ module Frameit
2
+ class FrameDownloader
3
+ FRAME_PATH = '.frameit/devices_frames_2'
4
+ HOST_URL = "https://fastlane.github.io/frameit-frames"
5
+
6
+ def download_frames
7
+ print_disclaimer
8
+
9
+ require 'json'
10
+ require 'fileutils'
11
+
12
+ UI.message("Downloading device frames...")
13
+ FileUtils.mkdir_p(templates_path)
14
+
15
+ frames_version = download_file("version.txt")
16
+ File.write(File.join(templates_path, "version.txt"), frames_version)
17
+ UI.important("Using frame version '#{frames_version}', you can optionally lock that version in your Framefile.json using `device_frame_version`")
18
+
19
+ files = JSON.parse(download_file("files.json"))
20
+ files.each_with_index do |current, index|
21
+ content = download_file(current, txt: "#{index + 1} of #{files.count} files")
22
+ File.write(File.join(templates_path, current), content)
23
+ end
24
+ File.write(File.join(templates_path, "offsets.json"), download_file("offsets.json"))
25
+
26
+ UI.success("Successfully downloaded all required image assets")
27
+ end
28
+
29
+ def frames_exist?(version: "latest")
30
+ Dir["#{templates_path}/*.png"].count > 0 && File.read(File.join(templates_path, "version.txt")).to_i > 0
31
+ end
32
+
33
+ def self.templates_path
34
+ File.join(ENV['HOME'], FRAME_PATH, Frameit.frames_version)
35
+ end
36
+
37
+ def templates_path
38
+ self.class.templates_path
39
+ end
40
+
41
+ def print_disclaimer
42
+ UI.header "Device frames disclaimer"
43
+ UI.important "All used device frames are available via Facebook Design: http://facebook.design/devices"
44
+ UI.message "----------------------------------------"
45
+ UI.message "While Facebook has redrawn and shares these assets for the benefit"
46
+ UI.message "of the design community, Facebook does not own any of the underlying"
47
+ UI.message "product or user interface designs."
48
+ UI.message "By accessing these assets, you agree to obtain all necessary permissions"
49
+ UI.message "from the underlying rights holders and/or adhere to any applicable brand"
50
+ UI.message "use guidelines before using them."
51
+ UI.message "Facebook disclaims all express or implied warranties with respect to these assets, including"
52
+ UI.message "non-infringement of intellectual property rights."
53
+ UI.message "----------------------------------------"
54
+ end
55
+
56
+ private
57
+
58
+ def download_file(path, txt: "file")
59
+ require 'uri'
60
+
61
+ url = File.join(HOST_URL, Frameit.frames_version, URI.escape(path))
62
+ UI.message("Downloading #{txt} from '#{url}' ...")
63
+ body = Excon.get(url).body
64
+ raise body if body.include?("<Error>")
65
+ return body
66
+ rescue => ex
67
+ UI.error(ex)
68
+ UI.user_error!("Error accessing URL '#{url}'")
69
+ end
70
+ end
71
+ end
@@ -3,89 +3,17 @@ module Frameit
3
3
  # Returns the image offset needed for a certain device type for a given orientation
4
4
  # uses deliver to detect the screen size
5
5
  def self.image_offset(screenshot)
6
- size = Deliver::AppScreenshot::ScreenSize
7
- case screenshot.orientation_name
8
- when Orientation::PORTRAIT
9
- case screenshot.screen_size
10
- when size::IOS_55
11
- return {
12
- 'offset' => '+41+146',
13
- 'width' => 541
14
- }
15
- when size::IOS_47
16
- return {
17
- 'offset' => "+43+154",
18
- 'width' => 530
19
- }
20
- when size::IOS_40
21
- if Frameit.config[:use_legacy_iphone5s]
22
- return {
23
- 'offset' => "+54+197",
24
- 'width' => 544
25
- }
26
- else
27
- return {
28
- 'offset' => "+48+178",
29
- 'width' => 485
30
- }
31
- end
32
- when size::IOS_35
33
- return {
34
- 'offset' => "+59+260",
35
- 'width' => 647
36
- }
37
- when size::IOS_IPAD
38
- return {
39
- 'offset' => '+47+135',
40
- 'width' => 737
41
- }
42
- when size::IOS_IPAD_PRO
43
- return {
44
- 'offset' => '+48+90',
45
- 'width' => 805
46
- }
47
- end
48
- when Orientation::LANDSCAPE
49
- case screenshot.screen_size
50
- when size::IOS_55
51
- return {
52
- 'offset' => "+146+41",
53
- 'width' => 960
54
- }
55
- when size::IOS_47
56
- return {
57
- 'offset' => "+153+41",
58
- 'width' => 946
59
- }
60
- when size::IOS_40
61
- if Frameit.config[:use_legacy_iphone5s]
62
- return {
63
- 'offset' => "+201+48",
64
- 'width' => 970
65
- }
66
- else
67
- return {
68
- 'offset' => "+177+41",
69
- 'width' => 859
70
- }
71
- end
72
- when size::IOS_35
73
- return {
74
- 'offset' => "+258+52",
75
- 'width' => 966
76
- }
77
- when size::IOS_IPAD
78
- return {
79
- 'offset' => '+135+47',
80
- 'width' => 983
81
- }
82
- when size::IOS_IPAD_PRO
83
- return {
84
- 'offset' => '+88+48',
85
- 'width' => 1075
86
- }
87
- end
6
+ require 'json'
7
+
8
+ unless @offsets
9
+ offsets_json_path = File.join(FrameDownloader.new.templates_path, "offsets.json")
10
+ UI.user_error!("Could not find offsets.json file at path '#{offsets_json_path}'") unless File.exist?(offsets_json_path)
11
+ @offsets = JSON.parse(File.read(offsets_json_path))
88
12
  end
13
+
14
+ offset_value = @offsets["portrait"][screenshot.device_name]
15
+ UI.error("Tried looking for offset information for 'portrait', #{screenshot.device_name}") unless offset_value
16
+ return offset_value
89
17
  end
90
18
  end
91
19
  end
@@ -12,6 +12,14 @@ module Frameit
12
12
  description: "Use white device frames. Alias for :white",
13
13
  optional: true,
14
14
  is_string: false),
15
+ FastlaneCore::ConfigItem.new(key: :rose_gold,
16
+ description: "Use rose gold device frames. Alias for :rose_gold",
17
+ optional: true,
18
+ is_string: false),
19
+ FastlaneCore::ConfigItem.new(key: :gold,
20
+ description: "Use gold device frames. Alias for :gold",
21
+ optional: true,
22
+ is_string: false),
15
23
  FastlaneCore::ConfigItem.new(key: :force_device_type,
16
24
  env_name: "FRAMEIT_FORCE_DEVICE_TYPE",
17
25
  description: "Forces a given device type, useful for Mac screenshots, as their sizes vary",
@@ -24,9 +32,13 @@ module Frameit
24
32
  end),
25
33
  FastlaneCore::ConfigItem.new(key: :use_legacy_iphone5s,
26
34
  env_name: "FRAMEIT_USE_LEGACY_IPHONE_5_S",
27
- optional: true,
28
35
  is_string: false,
29
36
  description: "use iPhone 5s instead of iPhone SE frames",
37
+ default_value: false),
38
+ FastlaneCore::ConfigItem.new(key: :use_legacy_iphone6s,
39
+ env_name: "FRAMEIT_USE_LEGACY_IPHONE_6_S",
40
+ is_string: false,
41
+ description: "Use iPhone 6s frames instead of iPhone 7 frames",
30
42
  default_value: false)
31
43
  ]
32
44
  end
@@ -4,13 +4,9 @@ require 'fastimage'
4
4
  module Frameit
5
5
  class Runner
6
6
  def initialize
7
- converter = FrameConverter.new
8
- if converter.frames_exist?
9
- # Just make sure, the PSD files are converted to PNG
10
- converter.convert_frames
11
- else
12
- # First run
13
- converter.run
7
+ downloader = FrameDownloader.new
8
+ unless downloader.frames_exist?
9
+ downloader.download_frames
14
10
  end
15
11
  end
16
12
 
@@ -18,6 +14,8 @@ module Frameit
18
14
  unless color
19
15
  color = Frameit::Color::BLACK
20
16
  color = Frameit::Color::SILVER if Frameit.config[:white] || Frameit.config[:silver]
17
+ color = Frameit::Color::GOLD if Frameit.config[:gold]
18
+ color = Frameit::Color::ROSE_GOLD if Frameit.config[:rose_gold]
21
19
  end
22
20
 
23
21
  screenshots = Dir.glob("#{path}/**/*.{png,PNG}").uniq # uniq because thanks to {png,PNG} there are duplicates
@@ -29,6 +27,8 @@ module Frameit
29
27
  next if full_path.include? "device_frames/" # these are the device frames the user is using
30
28
  next if full_path.downcase.include? "watch" # we don't care about watches right now
31
29
 
30
+ UI.message("Framing screenshot '#{full_path}'")
31
+
32
32
  begin
33
33
  screenshot = Screenshot.new(full_path, color)
34
34
  screenshot.frame!
@@ -38,7 +38,7 @@ module Frameit
38
38
  end
39
39
  end
40
40
  else
41
- UI.error "Could not find screenshots"
41
+ UI.error "Could not find screenshots in current directory: '#{File.expand_path(path)}'"
42
42
  end
43
43
  end
44
44
  end
@@ -22,30 +22,39 @@ module Frameit
22
22
  sizes = Deliver::AppScreenshot::ScreenSize
23
23
  case @screen_size
24
24
  when sizes::IOS_55
25
- return 'iPhone-6s-Plus'
25
+ return Frameit.config[:use_legacy_iphone6s] ? 'iPhone 6s Plus' : 'iPhone 7 Plus'
26
26
  when sizes::IOS_47
27
- return 'iPhone-6s'
27
+ return Frameit.config[:use_legacy_iphone6s] ? 'iPhone 6s' : 'iPhone 7'
28
28
  when sizes::IOS_40
29
- return Frameit.config[:use_legacy_iphone5s] ? 'iPhone_5s' : 'iPhone-SE'
29
+ return Frameit.config[:use_legacy_iphone5s] ? 'iPhone 5s' : 'iPhone SE'
30
30
  when sizes::IOS_35
31
- return 'iPhone_4'
31
+ return 'iPhone 4'
32
32
  when sizes::IOS_IPAD
33
- return 'iPad-mini'
33
+ return 'iPad Air 2'
34
34
  when sizes::IOS_IPAD_PRO
35
- return 'iPad-Pro'
35
+ return 'iPad Pro'
36
36
  when sizes::MAC
37
- return 'Mac'
37
+ return 'MacBook'
38
38
  else
39
39
  UI.error "Unknown device type for size #{@screen_size} for path '#{path}'"
40
40
  end
41
41
  end
42
42
 
43
+ def color
44
+ if !Frameit.config[:use_legacy_iphone6s] && @color == Frameit::Color::BLACK
45
+ if @screen_size == Deliver::AppScreenshot::ScreenSize::IOS_55 || @screen_size == Deliver::AppScreenshot::ScreenSize::IOS_47
46
+ return "Matte Black" # RIP space gray
47
+ end
48
+ end
49
+ return @color
50
+ end
51
+
43
52
  # Is the device a 3x device? (e.g. 6 Plus)
44
53
  def triple_density?
45
54
  (screen_size == Deliver::AppScreenshot::ScreenSize::IOS_55)
46
55
  end
47
56
 
48
- # Super old devices
57
+ # Super old devices (iPhone 4)
49
58
  def mini?
50
59
  (screen_size == Deliver::AppScreenshot::ScreenSize::IOS_35)
51
60
  end
@@ -1,84 +1,32 @@
1
1
  module Frameit
2
2
  # Responsible for finding the correct device
3
3
  class TemplateFinder
4
- class FilenameTransform
5
- def initialize(device_name)
6
- @device_name = device_name
7
- end
8
- end
9
-
10
- # Example: iPhone_5s_Vert_SpaceGray_sRGB
11
- class Type1Transform < FilenameTransform
12
- def transform(color, orientation)
13
- # Note the * on the end to handle the _sRGB part
14
- "#{@device_name}_#{orientation}_#{color}*"
15
- end
16
- end
17
-
18
- # Example: iPad-Pro-Space-Gray-vertical.png
19
- class Type2Transform < FilenameTransform
20
- def transform(color, orientation)
21
- fixed_color = color == 'SpaceGray' ? "Space-Gray" : "Silver"
22
- fixed_orientation = orientation == 'Horz' ? 'horizontal' : 'vertical'
23
- "#{@device_name}-#{fixed_color}-#{fixed_orientation}"
24
- end
25
- end
26
-
27
- # Example: iPhone-SE-Space-Gray
28
- # Note that 'vertical' is implied
29
- class Type3Transform < FilenameTransform
30
- def transform(color, orientation)
31
- fixed_color = color == 'SpaceGray' ? "Space-Gray" : "Silver"
32
- filename = "#{@device_name}-#{fixed_color}"
33
- if orientation == 'Horz'
34
- "#{filename}-horizontal"
35
- else
36
- filename
37
- end
38
- end
39
- end
40
-
41
- DEVICE_TO_TRANSFORM_TYPE = {
42
- 'iPhone-SE' => Type3Transform.new('iPhone-SE'),
43
- 'iPad-Pro' => Type2Transform.new('iPad-Pro'),
44
- 'iPad-mini' => Type2Transform.new('iPad-mini'),
45
- 'iPhone-6s' => Type2Transform.new('iPhone-6s'),
46
- 'iPhone-6s-Plus' => Type2Transform.new('iPhone-6s-Plus')
47
- }
48
-
49
4
  # This will detect the screen size and choose the correct template
50
5
  def self.get_template(screenshot)
51
6
  return nil if screenshot.mac?
52
7
 
53
- transformer = DEVICE_TO_TRANSFORM_TYPE[screenshot.device_name]
54
-
55
- # The "original" pattern is the type 1 transform
56
- # so if we don't have something more specific, go for that
57
- transformer ||= Type1Transform.new(screenshot.device_name)
58
- filename = transformer.transform(screenshot.color, screenshot.orientation_name)
8
+ filename = "Apple #{screenshot.device_name} #{screenshot.color}"
59
9
 
60
- templates_path = [ENV['HOME'], FrameConverter::FRAME_PATH].join('/')
61
- templates = Dir["../**/#{filename}.{png,jpg}"] # local directory
62
- templates += Dir["#{templates_path}/**/#{filename}.{png,jpg}"] # ~/.frameit folder
10
+ templates = Dir["#{FrameDownloader.templates_path}/#{filename}.{png,jpg}"] # ~/.frameit folder
63
11
 
64
- UI.verbose "Looking for #{filename} and found #{templates.count}"
12
+ UI.verbose "Looking for #{filename} and found #{templates.count} template(s)"
65
13
 
66
14
  if templates.count == 0
67
15
  if screenshot.screen_size == Deliver::AppScreenshot::ScreenSize::IOS_35
68
16
  UI.important "Unfortunately 3.5\" device frames were discontinued. Skipping screen '#{screenshot.path}'"
69
17
  UI.error "Looked for: '#{filename}.png'"
70
- elsif screenshot.device_name == 'iPhone-SE'
71
- UI.error "By default frameit uses the iPhone SE for screenshots"
72
- UI.error "Unable to find a frame #{filename}.png"
73
- UI.error "You can download iPhone-SE templates from '#{FrameConverter::DOWNLOAD_URL}'"
74
- UI.error "and store them in '#{templates_path}'"
75
- UI.error "\nIf you'd prefer to use the old iPhone 5s templates, add the option --use_legacy_iphone5s"
18
+ elsif screenshot.color == Frameit::Color::ROSE_GOLD || screenshot.color == Frameit::Color::GOLD
19
+ # Unfortunately not every device type is available in rose gold or gold
20
+ # This is why we can't have nice things #yatusabes
21
+ # fallback to a white iPhone, which looks similar
22
+ UI.important("Unfortunatey device type '#{screenshot.device_name}' is not available in #{screenshot.color}, falling back to silver...")
23
+ screenshot.color = Frameit::Color::SILVER
24
+ return self.get_template(screenshot)
76
25
  else
77
- UI.error "Could not find a valid template for screenshot '#{screenshot.path}'"
78
- UI.error "You can download new templates from '#{FrameConverter::DOWNLOAD_URL}'"
79
- UI.error "and store them in '#{templates_path}'"
80
- UI.error "Missing file: '#{filename}.png'"
26
+ UI.error("Couldn't find template for screenshot type '#{filename}'")
27
+ UI.error("Please run `frameit download_frames` to download the latest frames")
81
28
  end
29
+ return filename if Helper.test?
82
30
  return nil
83
31
  else
84
32
  return templates.first.tr(" ", "\ ")
@@ -1,3 +1,3 @@
1
1
  module Frameit
2
- VERSION = "2.8.0".freeze
2
+ VERSION = "3.0.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: frameit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-05 00:00:00.000000000 Z
11
+ date: 2016-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fastlane_core
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.52.1
19
+ version: 0.53.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: 1.0.0
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.52.1
29
+ version: 0.53.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.0.0
@@ -204,14 +204,14 @@ dependencies:
204
204
  requirements:
205
205
  - - "~>"
206
206
  - !ruby/object:Gem::Version
207
- version: 0.38.0
207
+ version: 0.44.0
208
208
  type: :development
209
209
  prerelease: false
210
210
  version_requirements: !ruby/object:Gem::Requirement
211
211
  requirements:
212
212
  - - "~>"
213
213
  - !ruby/object:Gem::Version
214
- version: 0.38.0
214
+ version: 0.44.0
215
215
  description: Quickly put your screenshots into the right device frames
216
216
  email:
217
217
  - frameit@krausefx.com
@@ -230,7 +230,7 @@ files:
230
230
  - lib/frameit/dependency_checker.rb
231
231
  - lib/frameit/device_types.rb
232
232
  - lib/frameit/editor.rb
233
- - lib/frameit/frame_converter.rb
233
+ - lib/frameit/frame_downloader.rb
234
234
  - lib/frameit/mac_editor.rb
235
235
  - lib/frameit/offsets.rb
236
236
  - lib/frameit/options.rb
@@ -1,99 +0,0 @@
1
- module Frameit
2
- class FrameConverter
3
- DOWNLOAD_URL = 'https://developer.apple.com/app-store/marketing/guidelines/#images'
4
- FRAME_PATH = '.frameit/devices_frames'
5
-
6
- def run
7
- self.setup_frames
8
- end
9
-
10
- def setup_frames
11
- UI.success "----------------------------------------------------"
12
- UI.success "Looks like you'd like to install new device templates"
13
- UI.success "The images can not be pre-installed due to licensing"
14
- UI.success "Press Enter to get started"
15
- UI.success "----------------------------------------------------"
16
- STDIN.gets
17
-
18
- system("open '#{DOWNLOAD_URL}'")
19
- UI.success "----------------------------------------------------"
20
- UI.success "Download the zip files for the following devices"
21
- UI.success "iPhone 6s, iPhone 6s Plus, iPhone SE, iPad mini 4 and iPad Pro"
22
- UI.success "You only need to download the devices you want to use"
23
- UI.success "Press Enter when you downloaded the zip files"
24
- UI.success "----------------------------------------------------"
25
- STDIN.gets
26
-
27
- loop do
28
- system("mkdir -p '#{templates_path}' && open '#{templates_path}'")
29
- UI.success "----------------------------------------------------"
30
- UI.success "Extract the downloaded files into the folder"
31
- UI.success "'#{templates_path}', which should be open in your Finder"
32
- UI.success "You can just copy the whole content into it."
33
- UI.success "Press Enter when you extracted the files into the given folder"
34
- UI.success "----------------------------------------------------"
35
- STDIN.gets
36
-
37
- if !frames_exist?
38
- UI.error "Sorry, I can't find the PSD files. Make sure you unzipped them into '#{templates_path}'"
39
- else
40
- break # everything is finished
41
- end
42
- end
43
-
44
- convert_frames
45
- end
46
-
47
- def frames_exist?
48
- (Dir["#{templates_path}/**/*.psd"].count + Dir["../**/*sRGB.png"].count) > 0
49
- end
50
-
51
- def templates_path
52
- "#{ENV['HOME']}/#{FRAME_PATH}"
53
- end
54
-
55
- # Converts all the PSD files to trimmed PNG files
56
- def convert_frames
57
- MiniMagick.configure do |config|
58
- config.validate_on_create = false
59
- end
60
-
61
- Dir["#{templates_path}/**/*.psd"].each do |psd|
62
- resulting_path = psd.gsub('.psd', '.png')
63
- next if File.exist?(resulting_path)
64
-
65
- UI.important "Converting PSD file '#{psd}'"
66
- image = MiniMagick::Image.open(psd)
67
-
68
- if psd =~ /iPhone-SE/
69
- UI.success "Removing white background 🚫 ⬜️"
70
-
71
- # The iPhone-SE screenshots from April 2016 have
72
- # 3 layers, a background, a product, and the 'put your image here' layer
73
- # imagemagick seems to add an additional layer with no label which this the
74
- # composite of all three. We want to remove the background and composite layer
75
- good_layers = image.layers.reject do |layer|
76
- label = layer.details['Properties']['label']
77
- label.to_s.length == 0 || label =~ /White B/i
78
- end
79
- product_layer = good_layers.shift
80
-
81
- good_layers.each do |layer|
82
- product_layer.layers << layer
83
- end
84
-
85
- image = product_layer
86
- end
87
-
88
- if image
89
- image.format 'png'
90
- image.trim
91
-
92
- image.write(resulting_path)
93
- else
94
- UI.error "Could not parse PSD file at path '#{psd}'"
95
- end
96
- end
97
- end
98
- end
99
- end