Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e8e7897d86 | |||
| 5a7d23f7e3 |
6
.env.default
Normal file
6
.env.default
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
KEY_STORE=<keystore.jks>
|
||||||
|
KEY_PASS=<passphrase>
|
||||||
|
SDK_PATH=$HOME/sdk
|
||||||
|
PUBLISH_PATH=$HOME/public/puzzlez
|
||||||
|
BUILD_PATH=./build
|
||||||
|
TARGET_PATH=./target
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@ config.json
|
|||||||
/log
|
/log
|
||||||
/ansible/*.retry
|
/ansible/*.retry
|
||||||
.npmrc
|
.npmrc
|
||||||
|
.env
|
||||||
28
Dockerfile
Normal file
28
Dockerfile
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
FROM ubuntu:noble AS base
|
||||||
|
RUN apt update && apt install -y \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
|
openjdk-11-jre \
|
||||||
|
protobuf-compiler \
|
||||||
|
jq
|
||||||
|
RUN node -v
|
||||||
|
RUN npm -v
|
||||||
|
|
||||||
|
FROM base AS builder
|
||||||
|
ENV GRADLE_USER_HOME=/sdk/gradle
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
COPY gulpfile.js protohx.json ./
|
||||||
|
COPY tasks ./tasks
|
||||||
|
COPY config.example.json ./config.example.json
|
||||||
|
RUN --mount=type=secret,id=KEY_STORE \
|
||||||
|
cat /run/secrets/KEY_STORE > ./key.jks
|
||||||
|
RUN --mount=type=secret,id=KEY_PASS,env=KEY_PASS \
|
||||||
|
jq --arg key_pass "$KEY_PASS" \
|
||||||
|
'.SdkDir = "/sdk" | .PublishDir = "/app/publish" | .Key.store = "key.jks" | .Key.pass = $key_pass' \
|
||||||
|
config.example.json > config.json
|
||||||
|
COPY src ./src
|
||||||
|
COPY dependencies ./dependencies
|
||||||
|
VOLUME ["/sdk", "/app/build", "/app/target", "/app/publish", "/app/src-gen"]
|
||||||
|
CMD ["npx", "gulp", "default"]
|
||||||
22
docker-compose.yaml
Normal file
22
docker-compose.yaml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: puzzlez
|
||||||
|
services:
|
||||||
|
builder:
|
||||||
|
container_name: puzzlez-builder
|
||||||
|
image: infernal-games/puzzlez-builder
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
secrets:
|
||||||
|
- KEY_STORE
|
||||||
|
- KEY_PASS
|
||||||
|
volumes:
|
||||||
|
- ${SDK_PATH}:/sdk
|
||||||
|
- ${BUILD_PATH}:/app/build
|
||||||
|
- ${TARGET_PATH}:/app/target
|
||||||
|
- ${PUBLISH_PATH}:/app/publish
|
||||||
|
- ./src-gen:/app/src-gen
|
||||||
|
|
||||||
|
secrets:
|
||||||
|
KEY_STORE:
|
||||||
|
file: $KEY_STORE
|
||||||
|
KEY_PASS:
|
||||||
|
environment: KEY_PASS
|
||||||
130
gulpfile.js
130
gulpfile.js
@@ -1,11 +1,10 @@
|
|||||||
const gulp = require('gulp');
|
const gulp = require("gulp");
|
||||||
const gulpClean = require('gulp-clean');
|
const gulpClean = require("gulp-clean");
|
||||||
const Config = require('./config.json');
|
const Config = require("./config.json");
|
||||||
const packageInfo = require('./package.json');
|
const packageInfo = require("./package.json");
|
||||||
const {System, Sdk, Haxe, Project} = require('gulp-haxetool');
|
const { System, Sdk, Haxe, Project } = require("gulp-haxetool");
|
||||||
const dateformat = require('dateformat');
|
const dateformat = require("dateformat");
|
||||||
const argv = require('yargs').argv;
|
const publish = require("./tasks/gulp-publish");
|
||||||
const publish = require('./tasks/gulp-publish');
|
|
||||||
|
|
||||||
if (packageInfo.haxe) {
|
if (packageInfo.haxe) {
|
||||||
Haxe.VERSION = packageInfo.haxe;
|
Haxe.VERSION = packageInfo.haxe;
|
||||||
@@ -20,37 +19,48 @@ if (Config.BuildDir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exports.clean = function clean() {
|
exports.clean = function clean() {
|
||||||
return gulp.src('target/*', {read: false}).pipe(gulpClean());
|
return gulp.src("target/*", { read: false }).pipe(gulpClean());
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.setup = function setup() {
|
||||||
|
const builder = Project.Builder.new(
|
||||||
|
app.config,
|
||||||
|
Project.Platform.ANDROID,
|
||||||
|
app.buildSystem,
|
||||||
|
);
|
||||||
|
return builder.prepare();
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.generate = function generate() {
|
exports.generate = function generate() {
|
||||||
return new Haxe().haxelib(['run', 'protohx', 'generate', 'protohx.json']).then(({stdout}) => {
|
return exports.setup().then(() =>
|
||||||
if (stdout.indexOf('FAIL') > -1) {
|
new Haxe()
|
||||||
|
.haxelib(["run", "protohx", "generate", "protohx.json"])
|
||||||
|
.then(({ stdout }) => {
|
||||||
|
if (stdout.indexOf("FAIL") > -1) {
|
||||||
throw stdout;
|
throw stdout;
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const config = new Project.Config({
|
const config = new Project.Config({
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Puzzle\'z',
|
title: "Puzzle'z",
|
||||||
filename: 'puzzlez',
|
filename: "puzzlez",
|
||||||
icon: 'src/app/resources/icon.png',
|
icon: "src/app/resources/icon.png",
|
||||||
pack: 'ru.m.puzzlez',
|
pack: "ru.m.puzzlez",
|
||||||
author: 'shmyga <shmyga.z@gmail.com>',
|
author: "shmyga <shmyga.z@gmail.com>",
|
||||||
company: 'MegaLoMania',
|
company: "MegaLoMania",
|
||||||
version: packageInfo.version + (Config.Develop ? '-SNAPSHOT' : ''),
|
version: packageInfo.version + (Config.Develop ? "-SNAPSHOT" : ""),
|
||||||
},
|
},
|
||||||
key: Config.Key,
|
key: Config.Key,
|
||||||
libs: packageInfo.haxeDependencies,
|
libs: packageInfo.haxeDependencies,
|
||||||
macros: [
|
macros: [
|
||||||
`CompilationOption.set('build','${dateformat(new Date(), 'yyyy-mm-dd HH:MM:ss')}')`,
|
`CompilationOption.set('build','${dateformat(new Date(), "yyyy-mm-dd HH:MM:ss")}')`,
|
||||||
`CompilationOption.set('UNSPLASH_KEY','${Config.UnsplashKey}')`,
|
`CompilationOption.set('UNSPLASH_KEY','${Config.UnsplashKey}')`,
|
||||||
`CompilationOption.set('PIXABAY_KEY','${Config.PixabayKey}')`,
|
`CompilationOption.set('PIXABAY_KEY','${Config.PixabayKey}')`,
|
||||||
],
|
],
|
||||||
flags: [
|
flags: ["proto_debug"],
|
||||||
'proto_debug',
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const app = new Project(
|
const app = new Project(
|
||||||
@@ -63,77 +73,67 @@ const app = new Project(
|
|||||||
Project.Platform.ANDROID,
|
Project.Platform.ANDROID,
|
||||||
],
|
],
|
||||||
config.branch({
|
config.branch({
|
||||||
name: 'app',
|
name: "app",
|
||||||
sources: [
|
sources: ["src-gen/haxe", "src/common/haxe", "src/app/haxe"],
|
||||||
'src-gen/haxe',
|
android: [
|
||||||
'src/common/haxe',
|
{
|
||||||
'src/app/haxe',
|
path: "dependencies/android",
|
||||||
|
extensions: ["ru.m.android.FileUtil"],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
android: [{
|
assets: ["src/app/resources"],
|
||||||
path: 'dependencies/android',
|
main: "ru.m.puzzlez.PuzzlezApp",
|
||||||
extensions: ['ru.m.android.FileUtil'],
|
|
||||||
}],
|
|
||||||
assets: [
|
|
||||||
'src/app/resources',
|
|
||||||
],
|
|
||||||
main: 'ru.m.puzzlez.PuzzlezApp',
|
|
||||||
meta: {
|
meta: {
|
||||||
width: 1280,
|
width: 1280,
|
||||||
height: 768,
|
height: 768,
|
||||||
},
|
},
|
||||||
flags: [
|
flags: ["app"],
|
||||||
'app',
|
|
||||||
]
|
|
||||||
}),
|
}),
|
||||||
).bind(module, gulp);
|
).bind(module, gulp);
|
||||||
|
|
||||||
const server = new Project(
|
const server = new Project(
|
||||||
Project.BuildSystem.HAXE,
|
Project.BuildSystem.HAXE,
|
||||||
[
|
[Project.Platform.NEKO, Project.Platform.CPP],
|
||||||
Project.Platform.NEKO,
|
|
||||||
Project.Platform.CPP,
|
|
||||||
],
|
|
||||||
config.branch({
|
config.branch({
|
||||||
name: 'server',
|
name: "server",
|
||||||
sources: [
|
sources: ["src-gen/haxe", "src/common/haxe", "src/server/haxe"],
|
||||||
'src-gen/haxe',
|
main: "ru.m.puzzlez.PuzzlezServer",
|
||||||
'src/common/haxe',
|
}),
|
||||||
'src/server/haxe',
|
|
||||||
],
|
|
||||||
main: 'ru.m.puzzlez.PuzzlezServer',
|
|
||||||
})
|
|
||||||
).bind(module, gulp);
|
).bind(module, gulp);
|
||||||
|
|
||||||
module.exports.publish = publish(packageInfo.name, packageInfo.version, Config.PublishDir, Config.PublishUrl);
|
module.exports.publish = publish(
|
||||||
|
packageInfo.name,
|
||||||
|
packageInfo.version,
|
||||||
|
Config.PublishDir,
|
||||||
|
Config.PublishUrl,
|
||||||
|
);
|
||||||
|
|
||||||
const defaultSeries = [
|
const defaultSeries = [
|
||||||
exports.clean,
|
exports.clean,
|
||||||
exports.generate,
|
exports.generate,
|
||||||
module.exports['app:flash:build'],
|
module.exports["app:flash:build"],
|
||||||
module.exports['app:flash:html'],
|
module.exports["app:flash:html"],
|
||||||
module.exports['app:html5:build'],
|
module.exports["app:html5:build"],
|
||||||
];
|
];
|
||||||
|
|
||||||
if (System.isLinux) {
|
if (System.isLinux) {
|
||||||
defaultSeries.push(
|
defaultSeries.push(
|
||||||
module.exports['app:linux:build'],
|
module.exports["app:linux:build"],
|
||||||
module.exports['app:linux:archive'],
|
module.exports["app:linux:archive"],
|
||||||
module.exports['app:linux:deb'],
|
module.exports["app:linux:deb"],
|
||||||
|
|
||||||
module.exports['app:android:build'],
|
module.exports["app:android:build"],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.isWindows) {
|
if (System.isWindows) {
|
||||||
defaultSeries.push(
|
defaultSeries.push(
|
||||||
module.exports['app:windows:build'],
|
module.exports["app:windows:build"],
|
||||||
module.exports['app:windows:archive'],
|
module.exports["app:windows:archive"],
|
||||||
module.exports['app:windows:installer'],
|
module.exports["app:windows:installer"],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultSeries.push(
|
defaultSeries.push(exports.publish);
|
||||||
exports.publish,
|
|
||||||
);
|
|
||||||
|
|
||||||
module.exports.default = gulp.series(defaultSeries);
|
module.exports.default = gulp.series(defaultSeries);
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"indentation": {
|
"indentation": {
|
||||||
"character": " "
|
"character": " "
|
||||||
|
},
|
||||||
|
"wrapping": {
|
||||||
|
"maxLineLength": 120
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "puzzlez",
|
"name": "puzzlez",
|
||||||
"version": "0.5.1",
|
"version": "0.6.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dateformat": "^3.0.3",
|
"dateformat": "^3.0.3",
|
||||||
|
|||||||
@@ -1,46 +1,53 @@
|
|||||||
{
|
{
|
||||||
"folders": [
|
"folders": [
|
||||||
{
|
{
|
||||||
"path": "."
|
"path": ".",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"settings": {
|
"settings": {
|
||||||
"haxe.executable": {
|
"haxe.executable": {
|
||||||
"path": "/home/shmyga/sdk/haxe/4.2.5/haxe",
|
"path": "/home/shmyga/sdk/haxe/4.2.5/haxe",
|
||||||
"env": {
|
"env": {
|
||||||
"HAXE_STD_PATH": "/home/shmyga/sdk/haxe/4.2.5/std"
|
"HAXE_STD_PATH": "/home/shmyga/sdk/haxe/4.2.5/std",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"haxe.configurations": [["build/app/flash/haxe/debug.hxml"]],
|
"haxe.configurations": [["build/app/flash/haxe/debug.hxml"]],
|
||||||
"haxe.displayServer": {
|
"haxe.displayServer": {
|
||||||
"arguments": [
|
"arguments": [
|
||||||
//"-v"
|
//"-v"
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"extensions": {
|
"extensions": {
|
||||||
"recommendations": ["nadako.vshaxe"]
|
"recommendations": ["nadako.vshaxe"],
|
||||||
},
|
},
|
||||||
"launch": {
|
"launch": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"args": ["app:flash:test"],
|
"args": ["${input:target}"],
|
||||||
"name": "app:flash:test",
|
"name": "${input:target}",
|
||||||
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
|
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"skipFiles": ["<node_internals>/**"],
|
"skipFiles": ["<node_internals>/**"],
|
||||||
"type": "node"
|
"type": "node",
|
||||||
|
"consoleTitle": "${input:target}",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"args": ["server:cpp:test"],
|
|
||||||
"name": "server:cpp:test",
|
|
||||||
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
|
|
||||||
"request": "launch",
|
|
||||||
"skipFiles": ["<node_internals>/**"],
|
|
||||||
"type": "node"
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"compounds": []
|
"inputs": [
|
||||||
}
|
{
|
||||||
|
"id": "target",
|
||||||
|
"description": "Please enter target name",
|
||||||
|
"options": [
|
||||||
|
"app:flash:test",
|
||||||
|
"app:html5:test",
|
||||||
|
"app:linux:test",
|
||||||
|
"server:cpp:test",
|
||||||
|
],
|
||||||
|
"type": "pickString",
|
||||||
|
"default": "app:flash:test",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"compounds": [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
7
scripts/build
Executable file
7
scripts/build
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname $(dirname "$0"))" || exit
|
||||||
|
|
||||||
|
source .env
|
||||||
|
mkdir -p "$SDK_PATH" "$PUBLISH_PATH" "$BUILD_PATH" "$TARGET_PATH" "src-gen"
|
||||||
|
docker compose run --rm --user $(id -u):$(id -g) --build --remove-orphans builder
|
||||||
@@ -8,6 +8,7 @@ import ru.m.puzzlez.render.part.IPartBuilder;
|
|||||||
import ru.m.puzzlez.settings.Settings;
|
import ru.m.puzzlez.settings.Settings;
|
||||||
import ru.m.puzzlez.source.AssetImageSource;
|
import ru.m.puzzlez.source.AssetImageSource;
|
||||||
import ru.m.puzzlez.source.FileImageSource;
|
import ru.m.puzzlez.source.FileImageSource;
|
||||||
|
import ru.m.puzzlez.source.NginxImageSource;
|
||||||
import ru.m.puzzlez.source.PixabayImageSource;
|
import ru.m.puzzlez.source.PixabayImageSource;
|
||||||
import ru.m.puzzlez.source.UnsplashImageSource;
|
import ru.m.puzzlez.source.UnsplashImageSource;
|
||||||
import ru.m.puzzlez.storage.GameStorage;
|
import ru.m.puzzlez.storage.GameStorage;
|
||||||
@@ -25,8 +26,9 @@ class PuzzlezApp {
|
|||||||
GameStorage;
|
GameStorage;
|
||||||
sourceBundle.register(new AssetImageSource());
|
sourceBundle.register(new AssetImageSource());
|
||||||
sourceBundle.register(new FileImageSource());
|
sourceBundle.register(new FileImageSource());
|
||||||
sourceBundle.register(new PixabayImageSource());
|
sourceBundle.register(new PixabayImageSource(CompilationOption.get("PIXABAY_KEY")));
|
||||||
sourceBundle.register(new UnsplashImageSource());
|
sourceBundle.register(new UnsplashImageSource(CompilationOption.get("UNSPLASH_KEY")));
|
||||||
|
sourceBundle.register(new NginxImageSource("https://home.shmyga.ru/puzzlez/"));
|
||||||
L.push(new TraceLogger());
|
L.push(new TraceLogger());
|
||||||
updater = new Updater(Const.instance.VERSION, "https://shmyga.ru/repo/puzzlez/packages.json");
|
updater = new Updater(Const.instance.VERSION, "https://shmyga.ru/repo/puzzlez/packages.json");
|
||||||
var app = new App();
|
var app = new App();
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ class PuzzlezTheme extends Theme {
|
|||||||
public function new() {
|
public function new() {
|
||||||
super({embed: true}, {light: "gray"}, {base: "4h"});
|
super({embed: true}, {light: "gray"}, {base: "4h"});
|
||||||
register(new Style("frame", ["geometry.padding" => Box.fromFloat(8),]));
|
register(new Style("frame", ["geometry.padding" => Box.fromFloat(8),]));
|
||||||
|
register(new Style("button.source", [
|
||||||
|
"geometry.width" => SizeValue.fromString("30%"),
|
||||||
|
"geometry.height" => SizeValue.fromString("40%"),
|
||||||
|
], "button"));
|
||||||
register(new Style("view", [
|
register(new Style("view", [
|
||||||
"skin.background.color" => colors.light,
|
"skin.background.color" => colors.light,
|
||||||
"skin.border.color" => colors.border,
|
"skin.border.color" => colors.border,
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ import ru.m.puzzlez.proto.game.ImageId;
|
|||||||
interface ImageSource extends DataSource<ImageId> {
|
interface ImageSource extends DataSource<ImageId> {
|
||||||
public var id(default, never):String;
|
public var id(default, never):String;
|
||||||
public function load(id:String, thumb:Bool = false):Promise<ImageValue>;
|
public function load(id:String, thumb:Bool = false):Promise<ImageValue>;
|
||||||
|
public function getCategories():Null<Promise<Array<String>>>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ class SpritePartView extends PartView {
|
|||||||
|
|
||||||
if (playerId != null) {
|
if (playerId != null) {
|
||||||
var rect = cast(part.rect, RectangleExt).clone();
|
var rect = cast(part.rect, RectangleExt).clone();
|
||||||
rect.x += (image.width - size.x) / 2;
|
rect.x = (image.width - size.x) / 2;
|
||||||
rect.y += (image.height - size.y) / 2;
|
rect.y = (image.height - size.y) / 2;
|
||||||
var path = builder.build(rect, part.bounds);
|
var path = builder.build(rect, part.bounds);
|
||||||
graphics.lineStyle(4, 0xffff00, 0.3);
|
graphics.lineStyle(4, 0xffff00, 0.3);
|
||||||
path.draw(graphics);
|
path.draw(graphics);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class AssetImageSource implements ImageSource {
|
|||||||
|
|
||||||
private var _data:Array<ImageId>;
|
private var _data:Array<ImageId>;
|
||||||
private var data(get, null):Array<ImageId>;
|
private var data(get, null):Array<ImageId>;
|
||||||
|
private var key:String;
|
||||||
|
|
||||||
private function get_data():Array<ImageId> {
|
private function get_data():Array<ImageId> {
|
||||||
if (_data == null) {
|
if (_data == null) {
|
||||||
@@ -21,11 +22,14 @@ class AssetImageSource implements ImageSource {
|
|||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function new() {}
|
public function new(key:String = "resources/image") {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
private function resolveData():Array<ImageId> {
|
private function resolveData():Array<ImageId> {
|
||||||
|
var keyLength = this.key.length;
|
||||||
return [
|
return [
|
||||||
for (name in Assets.list(AssetType.IMAGE).filter((name:String) -> name.substr(0, 15) == "resources/image"))
|
for (name in Assets.list(AssetType.IMAGE).filter((name:String) -> name.substr(0, keyLength) == this.key))
|
||||||
new ImageId().setSource(id).setId(name)
|
new ImageId().setSource(id).setId(name)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -41,4 +45,8 @@ class AssetImageSource implements ImageSource {
|
|||||||
public function load(id:String, thumb:Bool = false):Promise<ImageValue> {
|
public function load(id:String, thumb:Bool = false):Promise<ImageValue> {
|
||||||
return Promise.promise(ImageValue.BITMAP(Assets.getBitmapData(id)));
|
return Promise.promise(ImageValue.BITMAP(Assets.getBitmapData(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCategories():Null<Promise<Array<String>>> {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,4 +27,8 @@ class FileImageSource implements ImageSource {
|
|||||||
public function load(id:String, thumb:Bool = false):Promise<ImageValue> {
|
public function load(id:String, thumb:Bool = false):Promise<ImageValue> {
|
||||||
return storage.get(id).then(bytes -> ImageValue.BYTES(bytes));
|
return storage.get(id).then(bytes -> ImageValue.BYTES(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCategories():Null<Promise<Array<String>>> {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
78
src/app/haxe/ru/m/puzzlez/source/NginxImageSource.hx
Normal file
78
src/app/haxe/ru/m/puzzlez/source/NginxImageSource.hx
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package ru.m.puzzlez.source;
|
||||||
|
|
||||||
|
import hw.net.JsonLoader;
|
||||||
|
import promhx.Promise;
|
||||||
|
import ru.m.data.DataSource;
|
||||||
|
import ru.m.puzzlez.core.ImageSource;
|
||||||
|
import ru.m.puzzlez.core.ImageValue;
|
||||||
|
import ru.m.puzzlez.proto.game.ImageId;
|
||||||
|
|
||||||
|
enum abstract NginxResponseItemType(String) from String to String {
|
||||||
|
var FILE = "file";
|
||||||
|
var DIRECTORY = "directory";
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef NginxResponseItem = {
|
||||||
|
var name:String;
|
||||||
|
var type:NginxResponseItemType;
|
||||||
|
var mtime:String;
|
||||||
|
var size:Int;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef NginxResponse = Array<NginxResponseItem>;
|
||||||
|
|
||||||
|
class NginxImageSource implements ImageSource {
|
||||||
|
public var id(default, never):String = "nginx";
|
||||||
|
|
||||||
|
private var baseUrl:String;
|
||||||
|
|
||||||
|
public function new(baseUrl:String) {
|
||||||
|
this.baseUrl = baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildUrl(name:String):String {
|
||||||
|
return baseUrl + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPage(page:Page):Promise<DataPage<ImageId>> {
|
||||||
|
var category = page.filter.get("category");
|
||||||
|
return new JsonLoader<NginxResponse>().GET(category != null ? this.baseUrl + category + "/" : this.baseUrl)
|
||||||
|
.then((response:NginxResponse) -> {
|
||||||
|
var data:Array<ImageId> = [];
|
||||||
|
for (item in response) {
|
||||||
|
if (item.type == NginxResponseItemType.FILE) {
|
||||||
|
var itemId = category != null ? category + "@" + item.name : item.name;
|
||||||
|
data.push(new ImageId().setSource(id).setId(itemId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
page: page,
|
||||||
|
data: data,
|
||||||
|
total: response.length,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function load(id:String, thumb:Bool = false):Promise<ImageValue> {
|
||||||
|
var url = this.baseUrl + StringTools.replace(id, "@", "/");
|
||||||
|
if (thumb) {
|
||||||
|
var parts = url.split(".");
|
||||||
|
var index = parts.length - 2;
|
||||||
|
parts[index] = parts[index] + "-thumbnail";
|
||||||
|
url = parts.join(".");
|
||||||
|
}
|
||||||
|
return Promise.promise(ImageValue.URL(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCategories():Null<Promise<Array<String>>> {
|
||||||
|
return new JsonLoader<NginxResponse>().GET(this.baseUrl).then((response:NginxResponse) -> {
|
||||||
|
var data:Array<String> = [];
|
||||||
|
for (item in response) {
|
||||||
|
if (item.type == NginxResponseItemType.DIRECTORY) {
|
||||||
|
data.push(item.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,13 +14,13 @@ class PixabayImageSource implements ImageSource {
|
|||||||
|
|
||||||
private static var imageUrlsCache:Map<String, String> = new Map();
|
private static var imageUrlsCache:Map<String, String> = new Map();
|
||||||
|
|
||||||
public function new() {
|
public function new(key:String) {
|
||||||
var key:String = CompilationOption.get("PIXABAY_KEY");
|
|
||||||
api = new PixabayApi(key);
|
api = new PixabayApi(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPage(page:Page):Promise<DataPage<ImageId>> {
|
public function getPage(page:Page):Promise<DataPage<ImageId>> {
|
||||||
return this.api.getPage(page.index + 1, page.count, page.filter.get("category")).then((response:PixabayResponse) -> {
|
return this.api.getPage(page.index + 1, page.count, page.filter.get("category"))
|
||||||
|
.then((response:PixabayResponse) -> {
|
||||||
var data:Array<ImageId> = [];
|
var data:Array<ImageId> = [];
|
||||||
for (hit in response.hits) {
|
for (hit in response.hits) {
|
||||||
imageUrlsCache.set('${hit.id}', hit.largeImageURL);
|
imageUrlsCache.set('${hit.id}', hit.largeImageURL);
|
||||||
@@ -50,4 +50,8 @@ class PixabayImageSource implements ImageSource {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCategories():Null<Promise<Array<String>>> {
|
||||||
|
return Promise.promise(AbstractEnumTools.getValues(PixabayCategory));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ class UnsplashImageSource implements ImageSource {
|
|||||||
|
|
||||||
private static var resolver:ImageResolver;
|
private static var resolver:ImageResolver;
|
||||||
|
|
||||||
public function new() {
|
public function new(key:String) {
|
||||||
var key:String = CompilationOption.get("UNSPLASH_KEY");
|
|
||||||
api = new UnsplashApi(key);
|
api = new UnsplashApi(key);
|
||||||
resolver = new ImageResolver((imageId, thumb) -> {
|
resolver = new ImageResolver((imageId, thumb) -> {
|
||||||
return api.get(imageId).then(data -> thumb ? data.urls.small : data.urls.regular);
|
return api.get(imageId).then(data -> thumb ? data.urls.small : data.urls.regular);
|
||||||
@@ -60,7 +59,8 @@ class UnsplashImageSource implements ImageSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getPage(page:Page):Promise<DataPage<ImageId>> {
|
public function getPage(page:Page):Promise<DataPage<ImageId>> {
|
||||||
return this.api.getPage(page.index + 1, page.count, page.filter.get("category")).then((response:UnsplashResponse) -> {
|
return this.api.getPage(page.index + 1, page.count, page.filter.get("category"))
|
||||||
|
.then((response:UnsplashResponse) -> {
|
||||||
var data:Array<ImageId> = [];
|
var data:Array<ImageId> = [];
|
||||||
for (image in response.results) {
|
for (image in response.results) {
|
||||||
resolver.setValue(image.id, image.urls.small, true);
|
resolver.setValue(image.id, image.urls.small, true);
|
||||||
@@ -78,4 +78,9 @@ class UnsplashImageSource implements ImageSource {
|
|||||||
public function load(id:String, thumb:Bool = false):Promise<ImageValue> {
|
public function load(id:String, thumb:Bool = false):Promise<ImageValue> {
|
||||||
return resolver.resolve(id, thumb);
|
return resolver.resolve(id, thumb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCategories():Null<Promise<Array<String>>> {
|
||||||
|
// TODO: unsplash categories list
|
||||||
|
return Promise.promise([]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import ru.m.puzzlez.view.popup.PreviewPopup;
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public function onShow(state:GameState):Void {
|
override public function onShow(state:GameState):Void {
|
||||||
|
L.d("Frame", '$ID: ${state.preset.image.source}:${state.preset.image.id}');
|
||||||
onHide();
|
onHide();
|
||||||
if (state.online) {
|
if (state.online) {
|
||||||
// game = new NetworkGame(state);
|
// game = new NetworkGame(state);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ typedef GameListConfig = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public function onShow(data:GameListConfig):Void {
|
override public function onShow(data:GameListConfig):Void {
|
||||||
|
L.d("Frame", '$ID: $data');
|
||||||
games.reset();
|
games.reset();
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
header.text = data.title;
|
header.text = data.title;
|
||||||
|
|||||||
@@ -23,11 +23,18 @@ typedef ImageListConfig = {
|
|||||||
@:provide var switcher:FrameSwitcher;
|
@:provide var switcher:FrameSwitcher;
|
||||||
@:provide var sourceBundle:ImageSourceBundle;
|
@:provide var sourceBundle:ImageSourceBundle;
|
||||||
|
|
||||||
|
private var config:ImageListConfig;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super(ID);
|
super(ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function onShow(data:ImageListConfig):Void {
|
override public function onShow(data:ImageListConfig):Void {
|
||||||
|
if (data == null) {
|
||||||
|
data = config;
|
||||||
|
}
|
||||||
|
L.d("Frame", '$ID: $data');
|
||||||
|
config = data;
|
||||||
images.reset();
|
images.reset();
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
header.text = data.title;
|
header.text = data.title;
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import ru.m.puzzlez.view.common.PresetView;
|
|||||||
|
|
||||||
override public function onShow(data:ImageId):Void {
|
override public function onShow(data:ImageId):Void {
|
||||||
super.onShow(data);
|
super.onShow(data);
|
||||||
|
L.d("Frame", '$ID: ${data.source}:${data.id}');
|
||||||
imageId = data;
|
imageId = data;
|
||||||
selectSize(sizesView.data[sizesView.data.length - 1]);
|
selectSize(sizesView.data[sizesView.data.length - 1]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import hw.view.data.DataView;
|
|||||||
import hw.view.form.ButtonView;
|
import hw.view.form.ButtonView;
|
||||||
import hw.view.frame.FrameSwitcher;
|
import hw.view.frame.FrameSwitcher;
|
||||||
import hw.view.frame.FrameView;
|
import hw.view.frame.FrameView;
|
||||||
import ru.m.api.PixabayApi;
|
|
||||||
import ru.m.puzzlez.FileUtil;
|
import ru.m.puzzlez.FileUtil;
|
||||||
|
import ru.m.puzzlez.image.ImageSourceBundle;
|
||||||
import ru.m.puzzlez.proto.game.GameStatus;
|
import ru.m.puzzlez.proto.game.GameStatus;
|
||||||
import ru.m.puzzlez.storage.FileStorage;
|
import ru.m.puzzlez.storage.FileStorage;
|
||||||
import ru.m.puzzlez.storage.GameStorage;
|
import ru.m.puzzlez.storage.GameStorage;
|
||||||
@@ -27,24 +27,41 @@ import ru.m.update.Updater;
|
|||||||
|
|
||||||
@:provide var fileStorage:FileStorage;
|
@:provide var fileStorage:FileStorage;
|
||||||
@:provide var gameStorage:GameStorage;
|
@:provide var gameStorage:GameStorage;
|
||||||
|
@:provide var sourceBundle:ImageSourceBundle;
|
||||||
|
|
||||||
private var fileSource:ImageListConfig = {title: "Files", sourceId: "file"};
|
private var fileSource:ImageListConfig = {title: "Files", sourceId: "file"};
|
||||||
private var startedGames:GameListConfig = {title: "Started", source: gameStorage, filter: ["status" => GameStatus.STARTED]};
|
private var startedGames:GameListConfig = {
|
||||||
private var completedGames:GameListConfig = {title: "Completed", source: gameStorage, filter: ["status" => GameStatus.COMPLETE]};
|
title: "Started",
|
||||||
|
source: gameStorage,
|
||||||
|
filter: ["status" => GameStatus.STARTED]
|
||||||
|
};
|
||||||
|
private var completedGames:GameListConfig = {
|
||||||
|
title: "Completed",
|
||||||
|
source: gameStorage,
|
||||||
|
filter: ["status" => GameStatus.COMPLETE]
|
||||||
|
};
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super(ID);
|
super(ID);
|
||||||
var data:Array<ImageListConfig> = [];
|
var data:Array<ImageListConfig> = [];
|
||||||
// data.push({title: "Assets", sourceId: "asset"});
|
sourceBundle.get(fileSource.sourceId).getPage({index: 0, count: 0}).then((page) -> {
|
||||||
data.push(fileSource);
|
if (page.total > 0) {
|
||||||
for (type in AbstractEnumTools.getValues(PixabayCategory)) {
|
data.unshift(fileSource);
|
||||||
data.push({title: type, sourceId: "unsplash", filter: ["category" => type]});
|
sources.data = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sources.data = data;
|
||||||
|
sourceBundle.get("nginx").getCategories().then((categories) -> {
|
||||||
|
for (category in categories) {
|
||||||
|
data.push({title: category, sourceId: "nginx", filter: ["category" => category]});
|
||||||
}
|
}
|
||||||
sources.data = data;
|
sources.data = data;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private function sourceViewFactory(index:Int, source:ImageListConfig):ButtonView {
|
private function sourceViewFactory(index:Int, source:ImageListConfig):ButtonView {
|
||||||
var result = new ButtonView();
|
var result = new ButtonView();
|
||||||
|
result.style = "button.source";
|
||||||
result.text = source.title;
|
result.text = source.title;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -62,6 +79,7 @@ import ru.m.update.Updater;
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public function onShow(data:Dynamic):Void {
|
override public function onShow(data:Dynamic):Void {
|
||||||
|
L.d("Frame", '$ID');
|
||||||
appUpdater.check().then((info:Null<PackageInfo>) -> {
|
appUpdater.check().then((info:Null<PackageInfo>) -> {
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
updateButton.visible = true;
|
updateButton.visible = true;
|
||||||
@@ -74,9 +92,11 @@ import ru.m.update.Updater;
|
|||||||
private function refresh():Void {
|
private function refresh():Void {
|
||||||
gameStorage.getIndexPage({index: 0, count: 0, filter: startedGames.filter}).then(response -> {
|
gameStorage.getIndexPage({index: 0, count: 0, filter: startedGames.filter}).then(response -> {
|
||||||
startedButton.text = response.total > 0 ? 'Started (${response.total})' : 'Started';
|
startedButton.text = response.total > 0 ? 'Started (${response.total})' : 'Started';
|
||||||
|
startedButton.disabled = response.total == 0;
|
||||||
});
|
});
|
||||||
gameStorage.getIndexPage({index: 0, count: 0, filter: completedGames.filter}).then(response -> {
|
gameStorage.getIndexPage({index: 0, count: 0, filter: completedGames.filter}).then(response -> {
|
||||||
completedButton.text = response.total > 0 ? 'Completed (${response.total})' : 'Completed';
|
completedButton.text = response.total > 0 ? 'Completed (${response.total})' : 'Completed';
|
||||||
|
completedButton.disabled = response.total == 0;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package ru.m.storage;
|
package ru.m.storage;
|
||||||
|
|
||||||
import haxe.Unserializer;
|
|
||||||
import flash.net.SharedObject;
|
import flash.net.SharedObject;
|
||||||
|
import haxe.Serializer;
|
||||||
|
import haxe.Unserializer;
|
||||||
import haxe.crypto.Md5;
|
import haxe.crypto.Md5;
|
||||||
import haxe.io.Bytes;
|
import haxe.io.Bytes;
|
||||||
import haxe.Serializer;
|
|
||||||
import promhx.Promise;
|
import promhx.Promise;
|
||||||
import ru.m.data.DataSource;
|
import ru.m.data.DataSource;
|
||||||
|
|
||||||
@@ -124,7 +124,8 @@ class SharedObjectDataStorage<D, I> implements DataStorage<D, I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
applyOrder(page.order, values);
|
applyOrder(page.order, values);
|
||||||
var result:Array<I> = values.slice(page.index * page.count, page.index * page.count + page.count).map(value -> value.id);
|
var result:Array<I> = values.slice(page.index * page.count, page.index * page.count + page.count)
|
||||||
|
.map(value -> value.id);
|
||||||
return Promise.promise({
|
return Promise.promise({
|
||||||
page: page,
|
page: page,
|
||||||
total: values.length,
|
total: values.length,
|
||||||
@@ -138,7 +139,7 @@ class SharedObjectDataStorage<D, I> implements DataStorage<D, I> {
|
|||||||
return {
|
return {
|
||||||
page: indexPage.page,
|
page: indexPage.page,
|
||||||
total: indexPage.total,
|
total: indexPage.total,
|
||||||
data: data,
|
data: data.filter((item:D) -> item != null),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user