require_relative 'editor' require_relative 'mac_editor' require_relative 'device_types' require_relative 'module' require_relative 'device' module Frameit # Represents one screenshot class Screenshot attr_accessor :path # path to the screenshot attr_accessor :size # size in px array of 2 elements: height and width attr_accessor :device # device detected according to resolution, priority and settings attr_accessor :color # the color to use for the frame (from Frameit::Color) # path: Path to screenshot # color: Color to use for the frame def initialize(path, color, config, platform_command) UI.user_error!("Couldn't find file at path '#{path}'") unless File.exist?(path) @color = color @path = path @size = FastImage.size(path) # There are three ways how we can get settings to Frameit: # - options.rb # - gets parameters via CLI (e. g. fastlane run frameit use_platform:"android") or fastfile (Fastlane's global # settings for a given project) # - see Parameters in the doc # - contains default values and validates values # - accessed via Frameit.config[:key] # - default value is either general platform from fastfile or IOS if run directly # - lowest priority # - commands_generator.rb # - commands entered directly to CLI (e. g. fastlane frameit android) # - they are passed via constructors to other classes # - higher priority than options.rb (user may enter a command to override fastfile's global setting) # - config_parser.rb # - gets key / values from Framefile.json # - see Advanced usage in the doc # - both default and specific values can be entered in the file (filtered by file name) # - accessed via ConfigParser.fetch_value(screenshot.path)[key] (the ConfigParser's instance is passed # to Screenshot's constructor as config, i.e. we call config[key]) # - should have the highest priority, because user might set a specific value for a specific screenshot which # should override CLI parameters and fastfile global setting platform = config['use_platform'] || platform_command || Frameit.config[:use_platform] @device = Device.find_device_by_id_or_name(config['force_device_type'] || Frameit.config[:force_device_type]) || Device.detect_device(path, platform) end # Device name for a given screen size. Used to use the correct template def device_name @device.formatted_name # rubocop:enable Require/MissingRequireStatement end def default_color @device.default_color end def deliver_screen_id @device.deliver_screen_id end # Is the device a 3x device? (e.g. iPhone 6 Plus, iPhone X) def triple_density? !device.density_ppi.nil? && device.density_ppi > 400 end # Super old devices (iPhone 4) def mini? !device.density_ppi.nil? && device.density_ppi < 300 end def mac? device_name == 'MacBook' end # The name of the orientation of a screenshot. Used to find the correct template def orientation_name return Orientation::PORTRAIT if size[0] < size[1] return Orientation::LANDSCAPE end def frame_orientation filename = File.basename(self.path, ".*") block = Frameit.config[:force_orientation_block] unless block.nil? orientation = block.call(filename) valid = [:landscape_left, :landscape_right, :portrait, nil] UI.user_error("orientation_block must return #{valid[0..-2].join(', ')} or nil") unless valid.include?(orientation) end puts("Forced orientation: #{orientation}") unless orientation.nil? return orientation unless orientation.nil? return :portrait if self.orientation_name == Orientation::PORTRAIT return :landscape_right # Default landscape orientation end def portrait? return (frame_orientation == :portrait) end def landscape_left? return (frame_orientation == :landscape_left) end def landscape_right? return (frame_orientation == :landscape_right) end def landscape? return self.landscape_left? || self.landscape_right end def output_path path.gsub('.png', '_framed.png').gsub('.PNG', '_framed.png') end # If the framed screenshot was generated *before* the screenshot file, # then we must be outdated. def outdated? return true unless File.exist?(output_path) return File.mtime(path) > File.mtime(output_path) end def language @language ||= Pathname.new(path).parent.basename.to_s end def to_s self.path end end end