[refactoring] add GameListFrame

This commit is contained in:
2020-09-26 16:20:38 +03:00
parent 5e22d45d01
commit e6a11efe64
16 changed files with 139 additions and 123 deletions

View File

@@ -17,8 +17,9 @@
"openfl": "8.9.6", "openfl": "8.9.6",
"hxcpp": "4.0.52", "hxcpp": "4.0.52",
"svg": "1.1.3", "svg": "1.1.3",
"protohx": "0.4.6",
"haxe-crypto": "0.0.7" "haxe-crypto": "0.0.7"
}, },
"haxe": "4.0.5", "haxe": "4.1.4",
"dependencies": {} "dependencies": {}
} }

View File

@@ -8,7 +8,6 @@ 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.GameImageSource;
import ru.m.puzzlez.source.PixabayImageSource; import ru.m.puzzlez.source.PixabayImageSource;
import ru.m.puzzlez.storage.GameStorage; import ru.m.puzzlez.storage.GameStorage;
import ru.m.puzzlez.view.PuzzlezAppView; import ru.m.puzzlez.view.PuzzlezAppView;
@@ -27,7 +26,6 @@ class PuzzlezApp {
sourceBundle.register(new AssetImageSource()); sourceBundle.register(new AssetImageSource());
sourceBundle.register(new FileImageSource()); sourceBundle.register(new FileImageSource());
sourceBundle.register(new PixabayImageSource()); sourceBundle.register(new PixabayImageSource());
sourceBundle.register(new GameImageSource());
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();

View File

@@ -1,24 +0,0 @@
package ru.m.puzzlez.source;
import ru.m.puzzlez.proto.game.ImageId;
import promhx.Promise;
import ru.m.data.DataSource;
import ru.m.puzzlez.image.ImageSource;
import ru.m.puzzlez.storage.GameStorage;
class GameImageSource implements ImageSource {
public var id(default, never):String = "game";
@:provide private var storage:GameStorage;
public function new() {
}
public function getPage(page:Page):Promise<DataPage<ImageId>> {
return storage.getIndexPage(page);
}
public function load(id:String):Promise<ImageValue> {
throw "Unsupported";
}
}

View File

@@ -0,0 +1,46 @@
package ru.m.puzzlez.view;
import hw.view.frame.FrameSwitcher;
import ru.m.puzzlez.view.common.GameStateView;
import ru.m.view.DataList;
import hw.view.form.LabelView;
import ru.m.puzzlez.proto.game.GameState;
import ru.m.data.DataSource;
import ru.m.data.DataSource.Filter;
import hw.view.frame.FrameView;
typedef GameListConfig = {
var title:String;
var source:DataSource<GameState>;
@:optional var filter:Filter;
}
@:template class GameListFrame extends FrameView<GameListConfig> {
public static var ID(default, never) = "game_list";
@:view var header:LabelView;
@:view var games:DataList<GameState, GameStateView>;
@:provide var switcher:FrameSwitcher;
public function new() {
super(ID);
}
override public function onShow(data:GameListConfig):Void {
games.reset();
if (data != null) {
header.text = data.title;
games.page.filter = data.filter;
games.source = data.source;
games.refresh();
}
}
public function start(state:GameState):Void {
switcher.change(GameFrame.ID, state);
}
private function back():Void {
switcher.change(StartFrame.ID);
}
}

View File

@@ -0,0 +1,17 @@
---
style: frame
views:
- id: header
$type: hw.view.form.LabelView
style: label.header
- id: games
$type: ru.m.view.DataList
geometry.stretch: true
list.factory: ~ru.m.puzzlez.view.common.GameStateView.factory
+list.onDataSelect: ~start
- $type: hw.view.form.ButtonView
text: Back
geometry.position: absolute
geometry.hAlign: right
geometry.vAlign: top
+onPress: ~back()

View File

@@ -2,7 +2,6 @@ package ru.m.puzzlez.view;
import ru.m.puzzlez.view.common.ImageIdView; import ru.m.puzzlez.view.common.ImageIdView;
import ru.m.view.DataList; import ru.m.view.DataList;
import ru.m.puzzlez.storage.GameStorage;
import hw.view.form.LabelView; import hw.view.form.LabelView;
import hw.view.frame.FrameSwitcher; import hw.view.frame.FrameSwitcher;
import hw.view.frame.FrameView; import hw.view.frame.FrameView;
@@ -10,26 +9,25 @@ import ru.m.data.DataSource;
import ru.m.puzzlez.image.ImageSourceBundle; import ru.m.puzzlez.image.ImageSourceBundle;
import ru.m.puzzlez.proto.game.ImageId; import ru.m.puzzlez.proto.game.ImageId;
typedef ImageSourceConfig = { typedef ImageListConfig = {
var title:String; var title:String;
var sourceId:String; var sourceId:String;
@:optional var filter:Filter; @:optional var filter:Filter;
} }
@:template class ImageSourceFrame extends FrameView<ImageSourceConfig> { @:template class ImageListFrame extends FrameView<ImageListConfig> {
public static var ID = "source"; public static var ID = "image_list";
@:view var header:LabelView; @:view var header:LabelView;
@:view var images:DataList<ImageId, ImageIdView>; @:view var images:DataList<ImageId, ImageIdView>;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
@:provide var sourceBundle:ImageSourceBundle; @:provide var sourceBundle:ImageSourceBundle;
@:provide var gameStorage:GameStorage;
public function new() { public function new() {
super(ID); super(ID);
} }
override public function onShow(data:ImageSourceConfig):Void { override public function onShow(data:ImageListConfig):Void {
images.reset(); images.reset();
if (data != null) { if (data != null) {
header.text = data.title; header.text = data.title;
@@ -40,14 +38,8 @@ typedef ImageSourceConfig = {
} }
private function start(imageId:ImageId):Void { private function start(imageId:ImageId):Void {
gameStorage.get(imageId).then(state -> {
if (state != null) {
switcher.change(GameFrame.ID, state);
} else {
switcher.change(PresetFrame.ID, imageId); switcher.change(PresetFrame.ID, imageId);
} }
});
}
private function back():Void { private function back():Void {
switcher.change(StartFrame.ID); switcher.change(StartFrame.ID);

View File

@@ -61,6 +61,6 @@ import ru.m.puzzlez.view.common.PresetView;
} }
private function back():Void { private function back():Void {
switcher.change(ImageSourceFrame.ID); switcher.change(ImageListFrame.ID);
} }
} }

View File

@@ -6,8 +6,9 @@ views:
style: dark style: dark
factory: factory:
_start_: {$class: ru.m.puzzlez.view.StartFrame} _start_: {$class: ru.m.puzzlez.view.StartFrame}
_source_: {$class: ru.m.puzzlez.view.ImageSourceFrame} _image_list_: {$class: ru.m.puzzlez.view.ImageListFrame}
_preset_: {$class: ru.m.puzzlez.view.PresetFrame} _preset_: {$class: ru.m.puzzlez.view.PresetFrame}
_game_list_: {$class: ru.m.puzzlez.view.GameListFrame}
_game_: {$class: ru.m.puzzlez.view.GameFrame} _game_: {$class: ru.m.puzzlez.view.GameFrame}
- $type: hw.view.group.HGroupView - $type: hw.view.group.HGroupView
geometry.position: absolute geometry.position: absolute

View File

@@ -9,13 +9,14 @@ import ru.m.puzzlez.FileUtil;
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;
import ru.m.puzzlez.view.ImageSourceFrame; import ru.m.puzzlez.view.ImageListFrame;
import ru.m.puzzlez.view.GameListFrame;
import ru.m.update.Updater; import ru.m.update.Updater;
@:template class StartFrame extends FrameView<Dynamic> { @:template class StartFrame extends FrameView<Dynamic> {
public static var ID = "start"; public static var ID = "start";
@:view var sources:DataView<ImageSourceConfig, ButtonView>; @:view var sources:DataView<ImageListConfig, ButtonView>;
@:view var startedButton:ButtonView; @:view var startedButton:ButtonView;
@:view var completedButton:ButtonView; @:view var completedButton:ButtonView;
@:view var updateButton:ButtonView; @:view var updateButton:ButtonView;
@@ -25,13 +26,13 @@ import ru.m.update.Updater;
@:provide var fileStorage:FileStorage; @:provide var fileStorage:FileStorage;
@:provide var gameStorage:GameStorage; @:provide var gameStorage:GameStorage;
private var fileSource:ImageSourceConfig = {title: "Files", sourceId: "file"}; private var fileSource:ImageListConfig = {title: "Files", sourceId: "file"};
private var startedSource:ImageSourceConfig = {title: "Started", sourceId: "game", filter: ["status" => GameStatus.STARTED]}; private var startedGames:GameListConfig = {title: "Started", source: gameStorage, filter: ["status" => GameStatus.STARTED]};
private var completedSource:ImageSourceConfig = {title: "Completed", sourceId: "game", filter: ["status" => GameStatus.COMPLETE]}; 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<ImageSourceConfig> = []; var data:Array<ImageListConfig> = [];
data.push({title: "Assets", sourceId: "asset"}); data.push({title: "Assets", sourceId: "asset"});
data.push(fileSource); data.push(fileSource);
for (type in AbstractEnumTools.getValues(PixabayCategory)) { for (type in AbstractEnumTools.getValues(PixabayCategory)) {
@@ -40,7 +41,7 @@ import ru.m.update.Updater;
sources.data = data; sources.data = data;
} }
private function sourceViewFactory(index:Int, source:ImageSourceConfig):ButtonView { private function sourceViewFactory(index:Int, source:ImageListConfig):ButtonView {
var result = new ButtonView(); var result = new ButtonView();
result.text = source.title; result.text = source.title;
return result; return result;
@@ -52,8 +53,12 @@ import ru.m.update.Updater;
.then(_ -> showSource(fileSource)); .then(_ -> showSource(fileSource));
} }
public function showSource(source:ImageSourceConfig):Void { public function showSource(config:ImageListConfig):Void {
switcher.change(ImageSourceFrame.ID, source); switcher.change(ImageListFrame.ID, config);
}
public function showGames(config:GameListConfig):Void {
switcher.change(GameListFrame.ID, config);
} }
override public function onShow(data:Dynamic):Void { override public function onShow(data:Dynamic):Void {
@@ -67,10 +72,10 @@ import ru.m.update.Updater;
} }
private function refresh():Void { private function refresh():Void {
gameStorage.getIndexPage({index:0, count:0, filter:startedSource.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';
}); });
gameStorage.getIndexPage({index:0, count:0, filter:completedSource.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';
}); });
} }

View File

@@ -34,11 +34,11 @@ views:
- id: startedButton - id: startedButton
$type: hw.view.form.ButtonView $type: hw.view.form.ButtonView
text: Started text: Started
+onPress: ~showSource(startedSource) +onPress: ~showGames(startedGames)
- id: completedButton - id: completedButton
$type: hw.view.form.ButtonView $type: hw.view.form.ButtonView
text: Completed text: Completed
+onPress: ~showSource(completedSource) +onPress: ~showGames(completedGames)
- $type: hw.view.form.ButtonView - $type: hw.view.form.ButtonView
text: Upload text: Upload
geometry.margin.left: 30 geometry.margin.left: 30

View File

@@ -0,0 +1,34 @@
package ru.m.puzzlez.view.common;
import hw.view.theme.StyleId;
import hw.view.form.LabelView;
import hw.view.group.GroupView;
import ru.m.puzzlez.image.GameUtil;
import ru.m.puzzlez.proto.game.GameState;
@:template class GameStateView extends GroupView {
public var state(default, set):GameState;
private function set_state(value:GameState):GameState {
state = value;
image.imageId = state.preset.image;
var progress = GameUtil.calcProgress(state);
label.text = '${progress.complete}/${progress.total}';
return state;
}
@:view var image:ImageIdView;
@:view var label:LabelView;
public function new(?state:GameState, ?style: StyleId) {
super();
this.style = style;
if (state != null) {
this.state = state;
}
}
public static function factory(index:Int, value:GameState):GameStateView {
return new GameStateView(value, "view");
}
}

View File

@@ -0,0 +1,8 @@
---
views:
- id: image
$type: ru.m.puzzlez.view.common.ImageIdView
geometry.width: 100%
geometry.height: 100%
- id: label
$type: hw.view.form.LabelView

View File

@@ -1,79 +1,34 @@
package ru.m.puzzlez.view.common; package ru.m.puzzlez.view.common;
import ru.m.view.LoadingWrapper; import hw.view.theme.StyleId;
import ru.m.puzzlez.image.GameUtil;
import hw.view.popup.ConfirmView;
import hw.signal.Signal;
import hw.view.form.LabelView;
import hw.view.form.ButtonView;
import hw.view.group.GroupView; import hw.view.group.GroupView;
import hw.view.ImageView; import hw.view.ImageView;
import ru.m.puzzlez.image.ImageData; import ru.m.puzzlez.image.ImageData;
import ru.m.puzzlez.proto.game.ImageId; import ru.m.puzzlez.proto.game.ImageId;
import ru.m.puzzlez.storage.FileStorage; import ru.m.view.LoadingWrapper;
import ru.m.puzzlez.storage.GameStorage;
@:template class ImageIdView extends GroupView { @:template class ImageIdView extends GroupView {
public var imageId(default, set):ImageId; public var imageId(default, set):ImageId;
private function set_imageId(value:ImageId):ImageId { private function set_imageId(value:ImageId):ImageId {
imageId = value; imageId = value;
labelView.text = "";
cleanButton.visible = false;
removeButton.visible = false;
loading.promise = ImageData.fromImageId(imageId).resolve().then(data -> this.imageView.image = data); loading.promise = ImageData.fromImageId(imageId).resolve().then(data -> this.imageView.image = data);
gameStorage.get(imageId).then(state -> {
if (state != null) {
var progress = GameUtil.calcProgress(state);
labelView.text = '${progress.complete}/${progress.total}';
cleanButton.visible = true;
}
});
if (imageId.source == "file") {
fileStorage.get(imageId.id).then(value -> {
if (value != null) {
removeButton.visible = true;
}
});
}
return imageId; return imageId;
} }
@:view("image") var imageView:ImageView; @:view("image") var imageView:ImageView;
private var loading:LoadingWrapper; private var loading:LoadingWrapper;
@:view("label") var labelView:LabelView;
@:view("remove") var removeButton:ButtonView;
@:view("clean") var cleanButton:ButtonView;
@:provide private var fileStorage:FileStorage; public function new(?imageId:ImageId, ?style: StyleId) {
@:provide private var gameStorage:GameStorage;
public var onChange(default, null):Signal<Bool> = new Signal();
public function new(imageId:ImageId = null) {
super(); super();
this.style = style;
loading = new LoadingWrapper(this); loading = new LoadingWrapper(this);
if (imageId != null) { if (imageId != null) {
this.imageId = imageId; this.imageId = imageId;
} }
} }
private function removeImage():Void {
ConfirmView.confirm("Remove image?").then(result -> {
if (result) {
fileStorage.delete(imageId.id).then(_ -> onChange.emit(true));
}
});
}
private function cleanGame():Void {
ConfirmView.confirm("Remove game?").then(result -> {
if (result) {
gameStorage.delete(imageId).then(_ -> onChange.emit(true));
}
});
}
public static function factory(index:Int, value:ImageId):ImageIdView { public static function factory(index:Int, value:ImageId):ImageIdView {
return new ImageIdView(value); return new ImageIdView(value, "view");
} }
} }

View File

@@ -1,22 +1,7 @@
--- ---
style: view
views: views:
- id: image - id: image
$type: hw.view.ImageView $type: hw.view.ImageView
geometry.stretch: true geometry.stretch: true
stretch: false stretch: false
fillType: COVER fillType: COVER
- id: label
$type: hw.view.form.LabelView
- id: remove
$type: hw.view.form.ButtonView
visible: false
propagation: false
style: icon.control.small.close.red
+onPress: ~removeImage()
- id: clean
$type: hw.view.form.ButtonView
visible: false
propagation: false
style: icon.control.small.close.orange
+onPress: ~cleanGame()

View File

@@ -26,8 +26,6 @@ import ru.m.view.LoadingWrapper;
public function new() { public function new() {
super(); super();
trace("list", list);
trace("paginator", paginator);
loading = new LoadingWrapper(list); loading = new LoadingWrapper(list);
page = {index: 0, count: 6, order: [{field: "date", reverse: true}]}; page = {index: 0, count: 6, order: [{field: "date", reverse: true}]};
} }