rubysketch-solitaire 0.1.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +3 -0
- data/.gitignore +2 -0
- data/.hooks/post-commit +37 -0
- data/.hooks/pre-commit +69 -0
- data/ChangeLog.md +27 -0
- data/Gemfile.lock +10 -10
- data/Podfile.lock +33 -33
- data/README.md +8 -0
- data/Rakefile +107 -10
- data/RubySolitaire/Ad.swift +88 -0
- data/RubySolitaire/Assets.xcassets/AppIcon.appiconset/AppIcon.png +0 -0
- data/RubySolitaire/Assets.xcassets/AppIcon.appiconset/Contents.json +3 -87
- data/RubySolitaire/Base.lproj/Localizable.strings +6 -0
- data/RubySolitaire/Extensions.swift +5 -0
- data/RubySolitaire/GameView.swift +75 -13
- data/RubySolitaire/Helper.swift +70 -0
- data/RubySolitaire/MenuScreen.swift +141 -0
- data/RubySolitaire/RubySolitaireApp.swift +188 -1
- data/RubySolitaire/SafariView.swift +16 -0
- data/RubySolitaire/Strings.swift +48 -0
- data/RubySolitaire/ja.lproj/InfoPlist.strings +4 -0
- data/RubySolitaire/ja.lproj/Localizable.strings +6 -0
- data/VERSION +1 -1
- data/data/card.png +0 -0
- data/data/classicPSPWave.glsl +94 -0
- data/data/colorfulUnderwaterBubbles2.glsl +113 -0
- data/data/cosmic2.glsl +121 -0
- data/data/reflectiveHexes.glsl +219 -0
- data/fastlane/Fastfile +76 -0
- data/fastlane/metadata/copyright.txt +1 -0
- data/fastlane/metadata/en-US/apple_tv_privacy_policy.txt +1 -0
- data/fastlane/metadata/en-US/description.txt +5 -0
- data/fastlane/metadata/en-US/keywords.txt +1 -0
- data/fastlane/metadata/en-US/marketing_url.txt +1 -0
- data/fastlane/metadata/en-US/name.txt +1 -0
- data/fastlane/metadata/en-US/privacy_url.txt +1 -0
- data/fastlane/metadata/en-US/promotional_text.txt +1 -0
- data/fastlane/metadata/en-US/release_notes.txt +1 -0
- data/fastlane/metadata/en-US/subtitle.txt +1 -0
- data/fastlane/metadata/en-US/support_url.txt +1 -0
- data/fastlane/metadata/ja/apple_tv_privacy_policy.txt +1 -0
- data/fastlane/metadata/ja/description.txt +5 -0
- data/fastlane/metadata/ja/keywords.txt +1 -0
- data/fastlane/metadata/ja/marketing_url.txt +1 -0
- data/fastlane/metadata/ja/name.txt +1 -0
- data/fastlane/metadata/ja/privacy_url.txt +1 -0
- data/fastlane/metadata/ja/promotional_text.txt +1 -0
- data/fastlane/metadata/ja/release_notes.txt +1 -0
- data/fastlane/metadata/ja/subtitle.txt +1 -0
- data/fastlane/metadata/ja/support_url.txt +1 -0
- data/fastlane/metadata/primary_category.txt +1 -0
- data/fastlane/metadata/primary_first_sub_category.txt +1 -0
- data/fastlane/metadata/primary_second_sub_category.txt +1 -0
- data/fastlane/metadata/review_information/demo_password.txt +1 -0
- data/fastlane/metadata/review_information/demo_user.txt +1 -0
- data/fastlane/metadata/review_information/email_address.txt +1 -0
- data/fastlane/metadata/review_information/first_name.txt +0 -0
- data/fastlane/metadata/review_information/last_name.txt +0 -0
- data/fastlane/metadata/review_information/notes.txt +1 -0
- data/fastlane/metadata/review_information/phone_number.txt +0 -0
- data/fastlane/metadata/secondary_category.txt +1 -0
- data/fastlane/metadata/secondary_first_sub_category.txt +1 -0
- data/fastlane/metadata/secondary_second_sub_category.txt +1 -0
- data/lib/rubysketch/solitaire/background.rb +115 -12
- data/lib/rubysketch/solitaire/card.rb +10 -87
- data/lib/rubysketch/solitaire/common/animation.rb +34 -34
- data/lib/rubysketch/solitaire/common/button.rb +49 -19
- data/lib/rubysketch/solitaire/common/dialog.rb +78 -21
- data/lib/rubysketch/solitaire/common/scene.rb +15 -4
- data/lib/rubysketch/solitaire/common/settings.rb +15 -3
- data/lib/rubysketch/solitaire/common/timer.rb +2 -2
- data/lib/rubysketch/solitaire/common/transitions.rb +12 -6
- data/lib/rubysketch/solitaire/common/utils.rb +15 -0
- data/lib/rubysketch/solitaire/klondike.rb +382 -81
- data/lib/rubysketch/solitaire/places.rb +12 -102
- data/lib/rubysketch/solitaire/skin.rb +151 -0
- data/lib/rubysketch/solitaire.rb +33 -9
- data/main.rb +1 -0
- data/project.yml +85 -4
- metadata +55 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef707133db84935262b66e602ba0a645c8fc5570bbba72551e62080c07272859
|
4
|
+
data.tar.gz: 86db8fa959c1fc19a870ea73a9f75eeb0050525fd9565335c2150f6e475f5e27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3f2b2f9c834e732f73697ea2a525db3c43b6eade20cc548795e53df1a00456f69e42a7863ad6c68e993834b5aec472d215573f003aa439ced91099fa3fc1ac0
|
7
|
+
data.tar.gz: f400944134b3969d67a10b1f36a2ec95b4f3b2101b134cca3f851e7603254bd396d2038800a28f9287c7b8f51f0d0f7624afbe8ae0da36fb0428922c4883f9a9
|
data/.github/workflows/test.yml
CHANGED
data/.gitignore
CHANGED
data/.hooks/post-commit
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
|
4
|
+
def versions()
|
5
|
+
File.read(File.expand_path '../../ChangeLog.md', __dir__)
|
6
|
+
.split(/^\s*##\s*\[\s*v([\d\.]+)\s*\].*$/)
|
7
|
+
.slice(1..-1)
|
8
|
+
.each_slice(2)
|
9
|
+
.to_h
|
10
|
+
.transform_values do |changes|
|
11
|
+
changes.strip.lines
|
12
|
+
.group_by {|line| line[/^\W*(\[\w{2}\])/, 1]}
|
13
|
+
.map {|lang, lines|
|
14
|
+
[
|
15
|
+
lang[/\w+/],
|
16
|
+
lines.map {|line| line.sub(lang, '')}.join
|
17
|
+
]
|
18
|
+
}
|
19
|
+
.to_h
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
begin
|
25
|
+
ver = File.read(File.expand_path '../../VERSION', __dir__)[/[\d\.]+/]
|
26
|
+
changes = versions[ver].dig 'en'
|
27
|
+
tag = "v#{ver}"
|
28
|
+
tags = `git tag`.lines chomp: true
|
29
|
+
|
30
|
+
raise "no version found" unless ver
|
31
|
+
return if tags.include?(tag)
|
32
|
+
|
33
|
+
raise "no changes found" unless changes
|
34
|
+
|
35
|
+
puts "Tag '#{tag}'\n#{changes}"
|
36
|
+
`git tag -a -m "#{changes}" #{tag}`
|
37
|
+
end
|
data/.hooks/pre-commit
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
|
4
|
+
def filter_file(path, git_add: true, &block)
|
5
|
+
File.write path, block.call(File.read path)
|
6
|
+
`git add '#{path}'` if git_add
|
7
|
+
end
|
8
|
+
|
9
|
+
def ls_files(regexp)
|
10
|
+
`git ls-files`
|
11
|
+
.lines(chomp: true)
|
12
|
+
.select {|path| path =~ regexp}
|
13
|
+
end
|
14
|
+
|
15
|
+
def versions()
|
16
|
+
File.read(File.expand_path '../../ChangeLog.md', __dir__)
|
17
|
+
.split(/^\s*##\s*\[\s*v([\d\.]+)\s*\].*$/)
|
18
|
+
.slice(1..-1)
|
19
|
+
.each_slice(2)
|
20
|
+
.to_h
|
21
|
+
.transform_values do |changes|
|
22
|
+
changes.strip.lines
|
23
|
+
.group_by {|line| line[/^\W*(\[\w{2}\])/, 1]}
|
24
|
+
.map {|lang, lines|
|
25
|
+
[
|
26
|
+
lang[/\w+/],
|
27
|
+
lines.map {|line| line.sub(lang, '')}.join
|
28
|
+
]
|
29
|
+
}
|
30
|
+
.to_h
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
%w[config.yml GoogleService-Info.plist].each do |name|
|
36
|
+
raise "Do not commit #{name}" unless ls_files(/#{Regexp.escape name}/).empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
begin
|
41
|
+
filter_file File.expand_path('../../VERSION', __dir__) do
|
42
|
+
versions.keys.first
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
filter_file File.expand_path('../../project.yml', __dir__) do |body|
|
48
|
+
ver = versions.keys.first
|
49
|
+
marketing_ver = ver.split('.')
|
50
|
+
.map(&:to_i)
|
51
|
+
.tap {|a| a.pop while a.size > 3}
|
52
|
+
.join '.'
|
53
|
+
replace = -> s, key, ver {s.gsub /#{key}:\s*[\d\.]+/, "#{key}: #{ver}"}
|
54
|
+
|
55
|
+
body = replace.call body, 'CURRENT_PROJECT_VERSION', ver
|
56
|
+
body = replace.call body, 'MARKETING_VERSION', marketing_ver
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
begin
|
61
|
+
versions.values.first.tap do |changes|
|
62
|
+
changes.each do |lang, lines|
|
63
|
+
Dir.chdir File.expand_path('../..', __dir__) do
|
64
|
+
path = Dir.glob("fastlane/metadata/#{lang}*/release_notes.txt").first
|
65
|
+
filter_file(path) {lines}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/ChangeLog.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# RubySolitaire ChangeLog
|
2
|
+
|
3
|
+
|
4
|
+
## [v0.9.0] - 2023-06-20
|
5
|
+
|
6
|
+
- [en]First beta version
|
7
|
+
- [ja]最初のベータバージョン
|
8
|
+
|
9
|
+
|
10
|
+
## [v0.1.2] - 2023-06-16
|
11
|
+
|
12
|
+
- [en]Fixed some minor bugs
|
13
|
+
- [ja]軽微な不具合をいくつか修正
|
14
|
+
|
15
|
+
|
16
|
+
## [v0.1.1] - 2023-06-16
|
17
|
+
|
18
|
+
- [en]Added several types of backgrounds
|
19
|
+
- [en]Fixed some minor bugs
|
20
|
+
- [ja]背景の種類をいくつか追加
|
21
|
+
- [ja]軽微な不具合をいくつか修正
|
22
|
+
|
23
|
+
|
24
|
+
## [v0.1.0] - 2023-06-12
|
25
|
+
|
26
|
+
- [en]First stable version
|
27
|
+
- [ja]最初の安定バージョン
|
data/Gemfile.lock
CHANGED
@@ -16,17 +16,17 @@ GEM
|
|
16
16
|
artifactory (3.0.15)
|
17
17
|
atomos (0.1.3)
|
18
18
|
aws-eventstream (1.2.0)
|
19
|
-
aws-partitions (1.
|
20
|
-
aws-sdk-core (3.
|
19
|
+
aws-partitions (1.777.0)
|
20
|
+
aws-sdk-core (3.174.0)
|
21
21
|
aws-eventstream (~> 1, >= 1.0.2)
|
22
22
|
aws-partitions (~> 1, >= 1.651.0)
|
23
23
|
aws-sigv4 (~> 1.5)
|
24
24
|
jmespath (~> 1, >= 1.6.1)
|
25
|
-
aws-sdk-kms (1.
|
26
|
-
aws-sdk-core (~> 3, >= 3.
|
25
|
+
aws-sdk-kms (1.66.0)
|
26
|
+
aws-sdk-core (~> 3, >= 3.174.0)
|
27
27
|
aws-sigv4 (~> 1.1)
|
28
|
-
aws-sdk-s3 (1.
|
29
|
-
aws-sdk-core (~> 3, >= 3.
|
28
|
+
aws-sdk-s3 (1.123.1)
|
29
|
+
aws-sdk-core (~> 3, >= 3.174.0)
|
30
30
|
aws-sdk-kms (~> 1)
|
31
31
|
aws-sigv4 (~> 1.4)
|
32
32
|
aws-sigv4 (1.5.2)
|
@@ -85,7 +85,7 @@ GEM
|
|
85
85
|
escape (0.0.4)
|
86
86
|
ethon (0.16.0)
|
87
87
|
ffi (>= 1.15.0)
|
88
|
-
excon (0.
|
88
|
+
excon (0.100.0)
|
89
89
|
faraday (1.10.3)
|
90
90
|
faraday-em_http (~> 1.0)
|
91
91
|
faraday-em_synchrony (~> 1.0)
|
@@ -158,7 +158,7 @@ GEM
|
|
158
158
|
fourflusher (2.3.1)
|
159
159
|
fuzzy_match (2.0.4)
|
160
160
|
gh_inspector (1.1.3)
|
161
|
-
google-apis-androidpublisher_v3 (0.
|
161
|
+
google-apis-androidpublisher_v3 (0.43.0)
|
162
162
|
google-apis-core (>= 0.11.0, < 2.a)
|
163
163
|
google-apis-core (0.11.0)
|
164
164
|
addressable (~> 2.5, >= 2.5.1)
|
@@ -200,11 +200,11 @@ GEM
|
|
200
200
|
http-cookie (1.0.5)
|
201
201
|
domain_name (~> 0.5)
|
202
202
|
httpclient (2.8.3)
|
203
|
-
i18n (1.
|
203
|
+
i18n (1.14.1)
|
204
204
|
concurrent-ruby (~> 1.0)
|
205
205
|
jmespath (1.6.2)
|
206
206
|
json (2.6.3)
|
207
|
-
jwt (2.7.
|
207
|
+
jwt (2.7.1)
|
208
208
|
memoist (0.16.2)
|
209
209
|
mini_magick (4.12.0)
|
210
210
|
mini_mime (1.1.2)
|
data/Podfile.lock
CHANGED
@@ -1,36 +1,36 @@
|
|
1
1
|
PODS:
|
2
2
|
- CRuby (3.2.202)
|
3
|
-
- RubySketch (0.5.
|
4
|
-
- RubySketch/Beeps (= 0.5.
|
5
|
-
- RubySketch/Rays (= 0.5.
|
6
|
-
- RubySketch/Reflex (= 0.5.
|
7
|
-
- RubySketch/Rucy (= 0.5.
|
8
|
-
- RubySketch/Xot (= 0.5.
|
9
|
-
- RubySketch/Beeps (0.5.
|
10
|
-
- RubySketch/Beeps/Ext (= 0.5.
|
11
|
-
- RubySketch/Beeps/R8BrainFreeSrc (= 0.5.
|
12
|
-
- RubySketch/Beeps/STK (= 0.5.
|
13
|
-
- RubySketch/Beeps/Ext (0.5.
|
14
|
-
- RubySketch/Beeps/R8BrainFreeSrc (0.5.
|
15
|
-
- RubySketch/Beeps/STK (0.5.
|
16
|
-
- RubySketch/Rays (0.5.
|
17
|
-
- RubySketch/Rays/Clipper (= 0.5.
|
18
|
-
- RubySketch/Rays/Ext (= 0.5.
|
19
|
-
- RubySketch/Rays/Poly2Tri (= 0.5.
|
20
|
-
- RubySketch/Rays/SplineLib (= 0.5.
|
21
|
-
- RubySketch/Rays/Clipper (0.5.
|
22
|
-
- RubySketch/Rays/Ext (0.5.
|
23
|
-
- RubySketch/Rays/Poly2Tri (0.5.
|
24
|
-
- RubySketch/Rays/SplineLib (0.5.
|
25
|
-
- RubySketch/Reflex (0.5.
|
26
|
-
- RubySketch/Reflex/Box2D (= 0.5.
|
27
|
-
- RubySketch/Reflex/Ext (= 0.5.
|
28
|
-
- RubySketch/Reflex/Box2D (0.5.
|
29
|
-
- RubySketch/Reflex/Ext (0.5.
|
30
|
-
- RubySketch/Rucy (0.5.
|
31
|
-
- RubySketch/Rucy/Ext (= 0.5.
|
32
|
-
- RubySketch/Rucy/Ext (0.5.
|
33
|
-
- RubySketch/Xot (0.5.
|
3
|
+
- RubySketch (0.5.17):
|
4
|
+
- RubySketch/Beeps (= 0.5.17)
|
5
|
+
- RubySketch/Rays (= 0.5.17)
|
6
|
+
- RubySketch/Reflex (= 0.5.17)
|
7
|
+
- RubySketch/Rucy (= 0.5.17)
|
8
|
+
- RubySketch/Xot (= 0.5.17)
|
9
|
+
- RubySketch/Beeps (0.5.17):
|
10
|
+
- RubySketch/Beeps/Ext (= 0.5.17)
|
11
|
+
- RubySketch/Beeps/R8BrainFreeSrc (= 0.5.17)
|
12
|
+
- RubySketch/Beeps/STK (= 0.5.17)
|
13
|
+
- RubySketch/Beeps/Ext (0.5.17)
|
14
|
+
- RubySketch/Beeps/R8BrainFreeSrc (0.5.17)
|
15
|
+
- RubySketch/Beeps/STK (0.5.17)
|
16
|
+
- RubySketch/Rays (0.5.17):
|
17
|
+
- RubySketch/Rays/Clipper (= 0.5.17)
|
18
|
+
- RubySketch/Rays/Ext (= 0.5.17)
|
19
|
+
- RubySketch/Rays/Poly2Tri (= 0.5.17)
|
20
|
+
- RubySketch/Rays/SplineLib (= 0.5.17)
|
21
|
+
- RubySketch/Rays/Clipper (0.5.17)
|
22
|
+
- RubySketch/Rays/Ext (0.5.17)
|
23
|
+
- RubySketch/Rays/Poly2Tri (0.5.17)
|
24
|
+
- RubySketch/Rays/SplineLib (0.5.17)
|
25
|
+
- RubySketch/Reflex (0.5.17):
|
26
|
+
- RubySketch/Reflex/Box2D (= 0.5.17)
|
27
|
+
- RubySketch/Reflex/Ext (= 0.5.17)
|
28
|
+
- RubySketch/Reflex/Box2D (0.5.17)
|
29
|
+
- RubySketch/Reflex/Ext (0.5.17)
|
30
|
+
- RubySketch/Rucy (0.5.17):
|
31
|
+
- RubySketch/Rucy/Ext (= 0.5.17)
|
32
|
+
- RubySketch/Rucy/Ext (0.5.17)
|
33
|
+
- RubySketch/Xot (0.5.17)
|
34
34
|
|
35
35
|
DEPENDENCIES:
|
36
36
|
- CRuby (from `https://github.com/xord/cruby.git`)
|
@@ -47,12 +47,12 @@ CHECKOUT OPTIONS:
|
|
47
47
|
:commit: 133060a967e6acbf4aad3971b369acab86029065
|
48
48
|
:git: https://github.com/xord/cruby.git
|
49
49
|
RubySketch:
|
50
|
-
:commit:
|
50
|
+
:commit: 028cabc83f0038273a599d8f021e5b0ec2819d62
|
51
51
|
:git: https://github.com/xord/rubysketch.git
|
52
52
|
|
53
53
|
SPEC CHECKSUMS:
|
54
54
|
CRuby: f677262f16d7c714efd3021c90246296cf5bf9c3
|
55
|
-
RubySketch:
|
55
|
+
RubySketch: e933f316c15eb038c378894b6851e553fe08d7db
|
56
56
|
|
57
57
|
PODFILE CHECKSUM: 3ad0b358d0bc13ea451aa93df078142a38c591fc
|
58
58
|
|
data/README.md
CHANGED
@@ -16,6 +16,14 @@
|
|
16
16
|
$ ruby -rrubysketch/solitaire -e ''
|
17
17
|
```
|
18
18
|
|
19
|
+
## How to release to AppStore
|
20
|
+
|
21
|
+
### Upload to TestFlight on local macOS
|
22
|
+
|
23
|
+
1. Edit ChangeLog.md and commit
|
24
|
+
2. Make sure you have a config.yml file
|
25
|
+
3. run "rake release:testflight"
|
26
|
+
|
19
27
|
## License
|
20
28
|
|
21
29
|
see [LICENSE](LICENSE) file
|
data/Rakefile
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
.map {|s| File.expand_path "#{s}/lib", __dir__}
|
6
6
|
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
7
7
|
|
8
|
+
require 'yaml'
|
9
|
+
require 'base64'
|
8
10
|
require 'xot/rake'
|
9
11
|
|
10
12
|
require 'xot/extension'
|
@@ -15,18 +17,48 @@ EXTENSIONS = [RubySketch::Solitaire]
|
|
15
17
|
|
16
18
|
GEMNAME = "rubysketch-#{target.name.downcase}"
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
PROJECT = 'project.yml'
|
21
|
+
CHANGELOG = 'ChangeLog.md'
|
22
|
+
|
23
|
+
APP_NAME = ENV['APP_NAME'] = "Ruby#{target.name}"
|
24
|
+
APP_ID = ENV['APP_ID'] = "org.xord.#{APP_NAME}"
|
25
|
+
XCWORKSPACE = "#{APP_NAME}.xcworkspace"
|
26
|
+
XCODEPROJ = "#{APP_NAME}.xcodeproj"
|
27
|
+
GINFO_PLIST = 'RubySolitaire/GoogleService-Info.plist'
|
21
28
|
|
22
29
|
BUNDLE_DIR = 'vendor/bundle'
|
23
30
|
PODS_DIR = 'Pods'
|
24
31
|
|
25
32
|
|
33
|
+
def config(key)
|
34
|
+
$config ||= YAML.load_file(File.expand_path 'config.yml', __dir__) rescue {}
|
35
|
+
key = key.to_s.upcase
|
36
|
+
ENV[key] or $config[key]
|
37
|
+
end
|
38
|
+
|
39
|
+
def versions()
|
40
|
+
File.read(CHANGELOG)
|
41
|
+
.split(/^\s*##\s*\[\s*v([\d\.]+)\s*\].*$/)
|
42
|
+
.slice(1..-1)
|
43
|
+
.each_slice(2)
|
44
|
+
.to_h
|
45
|
+
.transform_values do |changes|
|
46
|
+
changes.strip.lines
|
47
|
+
.group_by {|line| line[/^\W*(\[\w{2}\])/, 1]}
|
48
|
+
.map {|lang, lines|
|
49
|
+
[
|
50
|
+
lang[/\w+/],
|
51
|
+
lines.map {|line| line.sub(lang, '')}.join
|
52
|
+
]
|
53
|
+
}
|
54
|
+
.to_h
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
26
59
|
default_tasks
|
27
60
|
build_ruby_gem
|
28
61
|
|
29
|
-
|
30
62
|
task :build => 'xcode:build'
|
31
63
|
|
32
64
|
task :xcode => 'xcode:open'
|
@@ -49,8 +81,8 @@ namespace :xcode do
|
|
49
81
|
sh %( xcodebuild clean ) if File.exist?(XCODEPROJ)
|
50
82
|
end
|
51
83
|
|
52
|
-
task :clobber
|
53
|
-
sh %( rm -rf #{XCWORKSPACE} #{XCODEPROJ} )
|
84
|
+
task :clobber do
|
85
|
+
sh %( rm -rf #{XCWORKSPACE} #{XCODEPROJ} #{GINFO_PLIST} )
|
54
86
|
end
|
55
87
|
|
56
88
|
task :build => XCWORKSPACE do
|
@@ -63,10 +95,14 @@ namespace :xcode do
|
|
63
95
|
|
64
96
|
file XCWORKSPACE => [BUNDLE_DIR, PODS_DIR]
|
65
97
|
|
66
|
-
file XCODEPROJ do
|
98
|
+
file XCODEPROJ => 'scripts:setup' do
|
99
|
+
plist = config(:ginfo_plist)&.then {|s| Base64.decode64 s}
|
100
|
+
File.write GINFO_PLIST, plist if plist
|
101
|
+
|
67
102
|
sh %( xcodegen generate )
|
103
|
+
sh %( fastlane setup_code_signing )
|
68
104
|
end
|
69
|
-
end
|
105
|
+
end# xcode
|
70
106
|
|
71
107
|
|
72
108
|
namespace :bundle do
|
@@ -82,7 +118,7 @@ namespace :bundle do
|
|
82
118
|
sh %( bundle install )
|
83
119
|
raise "failed to bundle install" unless File.exist? BUNDLE_DIR
|
84
120
|
end
|
85
|
-
end
|
121
|
+
end# bundle
|
86
122
|
|
87
123
|
|
88
124
|
namespace :pods do
|
@@ -97,4 +133,65 @@ namespace :pods do
|
|
97
133
|
file PODS_DIR => [BUNDLE_DIR, XCODEPROJ] do
|
98
134
|
sh %( bundle exec pod install --verbose --repo-update )
|
99
135
|
end
|
100
|
-
end
|
136
|
+
end# pods
|
137
|
+
|
138
|
+
|
139
|
+
namespace :release do
|
140
|
+
task :testflight => 'release:setup' do
|
141
|
+
ENV['MATCH_TYPE'] = 'AppStore'
|
142
|
+
sh %( fastlane setup_code_signing )
|
143
|
+
|
144
|
+
ENV['CHANGELOG'] = versions.values.first['en']
|
145
|
+
sh %( fastlane release_testflight )
|
146
|
+
end
|
147
|
+
|
148
|
+
task :setup => ['xcode:clobber', :clobber, XCWORKSPACE] do
|
149
|
+
replace = -> s, key, value {s.gsub /#{key}:\s*.+/, "#{key}: #{value}"}
|
150
|
+
|
151
|
+
filter_file PROJECT do |body|
|
152
|
+
body = replace.call(
|
153
|
+
body,
|
154
|
+
'GADApplicationIdentifier',
|
155
|
+
config(:gad_app_id))
|
156
|
+
body = replace.call(
|
157
|
+
body,
|
158
|
+
'GADGameScreenBottomBanner',
|
159
|
+
config(:gad_game_screen_bottom_banner))
|
160
|
+
body = replace.call(
|
161
|
+
body,
|
162
|
+
'GADGameScreenInterstitial',
|
163
|
+
config(:gad_game_screen_interstitial))
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
namespace :match do
|
168
|
+
task(:update) {sh %( fastlane match_update )}
|
169
|
+
task(:fetch) {sh %( fastlane match_fetch )}
|
170
|
+
task(:delete) {sh %( fastlane match_delete )}
|
171
|
+
|
172
|
+
task :refresh => ['fastlane:match:delete', 'fastlane:match:update']
|
173
|
+
|
174
|
+
task :fetch_new_devices do
|
175
|
+
sh %( fastlane match development --force_for_new_devices )
|
176
|
+
end
|
177
|
+
end# match
|
178
|
+
end# release
|
179
|
+
|
180
|
+
|
181
|
+
namespace :scripts do
|
182
|
+
task :setup => 'scripts:hooks:setup'
|
183
|
+
|
184
|
+
namespace :hooks do
|
185
|
+
hooks = Dir.glob('.hooks/*')
|
186
|
+
.map {|path| [path, ".git/hooks/#{File.basename path}"]}
|
187
|
+
.to_h
|
188
|
+
|
189
|
+
task :setup => hooks.values
|
190
|
+
|
191
|
+
hooks.each do |from, to|
|
192
|
+
file to => from do
|
193
|
+
sh %( cp #{from} #{to} )
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end# scripts
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import SwiftUI
|
2
|
+
import GoogleMobileAds
|
3
|
+
|
4
|
+
|
5
|
+
struct AdBannerView: UIViewRepresentable {
|
6
|
+
let width: Double
|
7
|
+
let adUnitID: String
|
8
|
+
let rootViewController: UIViewController
|
9
|
+
|
10
|
+
func makeUIView(context: Context) -> some UIView {
|
11
|
+
let view = GADBannerView(adSize: GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth(width))
|
12
|
+
view.adUnitID = adUnitID
|
13
|
+
view.rootViewController = rootViewController
|
14
|
+
view.load(GADRequest())
|
15
|
+
return view
|
16
|
+
}
|
17
|
+
|
18
|
+
func updateUIView(_ uiView: UIViewType, context: Context) {
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
|
23
|
+
class InterstitialAd: NSObject, GADFullScreenContentDelegate, ObservableObject {
|
24
|
+
|
25
|
+
let adUnitID: String
|
26
|
+
|
27
|
+
@Published var ready = false
|
28
|
+
|
29
|
+
private var ad: GADInterstitialAd? {
|
30
|
+
didSet {
|
31
|
+
ready = ad != nil
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
private var closed: ((Error?) -> Void)?
|
36
|
+
|
37
|
+
init(adUnitID: String) {
|
38
|
+
self.adUnitID = adUnitID
|
39
|
+
super.init()
|
40
|
+
load()
|
41
|
+
}
|
42
|
+
|
43
|
+
func load() {
|
44
|
+
if ad != nil {
|
45
|
+
return
|
46
|
+
}
|
47
|
+
GADInterstitialAd.load(withAdUnitID: adUnitID, request: GADRequest()) { [weak self] ad, error in
|
48
|
+
guard error == nil, let self = self else {
|
49
|
+
print("Failed to load interstitial ad: \(error?.localizedDescription ?? "Unknown")")
|
50
|
+
return
|
51
|
+
}
|
52
|
+
|
53
|
+
self.ad = ad
|
54
|
+
self.ad?.fullScreenContentDelegate = self
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
func show(rootViewController: UIViewController, closed: @escaping (Error?) -> Void) {
|
59
|
+
guard let ad = ad else {
|
60
|
+
closed(InterstitialAdCancelError())
|
61
|
+
return load()
|
62
|
+
}
|
63
|
+
|
64
|
+
self.closed = closed
|
65
|
+
ad.present(fromRootViewController: rootViewController)
|
66
|
+
}
|
67
|
+
|
68
|
+
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
|
69
|
+
self.ad = nil
|
70
|
+
load()
|
71
|
+
if let closed = self.closed {
|
72
|
+
closed(nil)
|
73
|
+
self.closed = nil
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
|
78
|
+
self.ad = nil
|
79
|
+
load()
|
80
|
+
if let closed = self.closed {
|
81
|
+
closed(error)
|
82
|
+
self.closed = nil
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
|
88
|
+
class InterstitialAdCancelError: Error {}
|
Binary file
|
@@ -1,93 +1,9 @@
|
|
1
1
|
{
|
2
2
|
"images" : [
|
3
3
|
{
|
4
|
-
"
|
5
|
-
"
|
6
|
-
"
|
7
|
-
},
|
8
|
-
{
|
9
|
-
"idiom" : "iphone",
|
10
|
-
"scale" : "3x",
|
11
|
-
"size" : "20x20"
|
12
|
-
},
|
13
|
-
{
|
14
|
-
"idiom" : "iphone",
|
15
|
-
"scale" : "2x",
|
16
|
-
"size" : "29x29"
|
17
|
-
},
|
18
|
-
{
|
19
|
-
"idiom" : "iphone",
|
20
|
-
"scale" : "3x",
|
21
|
-
"size" : "29x29"
|
22
|
-
},
|
23
|
-
{
|
24
|
-
"idiom" : "iphone",
|
25
|
-
"scale" : "2x",
|
26
|
-
"size" : "40x40"
|
27
|
-
},
|
28
|
-
{
|
29
|
-
"idiom" : "iphone",
|
30
|
-
"scale" : "3x",
|
31
|
-
"size" : "40x40"
|
32
|
-
},
|
33
|
-
{
|
34
|
-
"idiom" : "iphone",
|
35
|
-
"scale" : "2x",
|
36
|
-
"size" : "60x60"
|
37
|
-
},
|
38
|
-
{
|
39
|
-
"idiom" : "iphone",
|
40
|
-
"scale" : "3x",
|
41
|
-
"size" : "60x60"
|
42
|
-
},
|
43
|
-
{
|
44
|
-
"idiom" : "ipad",
|
45
|
-
"scale" : "1x",
|
46
|
-
"size" : "20x20"
|
47
|
-
},
|
48
|
-
{
|
49
|
-
"idiom" : "ipad",
|
50
|
-
"scale" : "2x",
|
51
|
-
"size" : "20x20"
|
52
|
-
},
|
53
|
-
{
|
54
|
-
"idiom" : "ipad",
|
55
|
-
"scale" : "1x",
|
56
|
-
"size" : "29x29"
|
57
|
-
},
|
58
|
-
{
|
59
|
-
"idiom" : "ipad",
|
60
|
-
"scale" : "2x",
|
61
|
-
"size" : "29x29"
|
62
|
-
},
|
63
|
-
{
|
64
|
-
"idiom" : "ipad",
|
65
|
-
"scale" : "1x",
|
66
|
-
"size" : "40x40"
|
67
|
-
},
|
68
|
-
{
|
69
|
-
"idiom" : "ipad",
|
70
|
-
"scale" : "2x",
|
71
|
-
"size" : "40x40"
|
72
|
-
},
|
73
|
-
{
|
74
|
-
"idiom" : "ipad",
|
75
|
-
"scale" : "1x",
|
76
|
-
"size" : "76x76"
|
77
|
-
},
|
78
|
-
{
|
79
|
-
"idiom" : "ipad",
|
80
|
-
"scale" : "2x",
|
81
|
-
"size" : "76x76"
|
82
|
-
},
|
83
|
-
{
|
84
|
-
"idiom" : "ipad",
|
85
|
-
"scale" : "2x",
|
86
|
-
"size" : "83.5x83.5"
|
87
|
-
},
|
88
|
-
{
|
89
|
-
"idiom" : "ios-marketing",
|
90
|
-
"scale" : "1x",
|
4
|
+
"filename" : "AppIcon.png",
|
5
|
+
"idiom" : "universal",
|
6
|
+
"platform" : "ios",
|
91
7
|
"size" : "1024x1024"
|
92
8
|
}
|
93
9
|
],
|