diff --git a/Project.toml b/Project.toml index 29cc48f6..3d1873f7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,7 @@ name = "Stipple" uuid = "4acbeb90-81a0-11ea-1966-bdaff8155998" authors = ["Adrian "] + version = "0.30.7" [deps] diff --git a/src/ModelStorage.jl b/src/ModelStorage.jl index 17022228..ee709154 100644 --- a/src/ModelStorage.jl +++ b/src/ModelStorage.jl @@ -12,8 +12,10 @@ function model_id(::Type{M}) where M Symbol(Stipple.routename(M)) end -function store(model::M) where M - GenieSession.set!(model_id(M), model) +function store(model::M, force::Bool = false) where M + # do not overwrite stored model + (GenieSession.get(model_id(M), nothing) === nothing || force) && GenieSession.set!(model_id(M), model) + nothing end @@ -22,16 +24,19 @@ function init_from_storage( t::Type{M}; kwargs...) where M model = Stipple.init(M; channel, kwargs...) stored_model = GenieSession.get(model_id(M), nothing) - CM = Stipple.get_concrete_type(M) + for f in fieldnames(CM) field = getfield(model, f) + if field isa Reactive # restore fields only if a stored model exists, if the field is not part of the internal fields and is not write protected - ( - isnothing(stored_model) || f ∈ [Stipple.CHANNELFIELDNAME, Stipple.AUTOFIELDS...] || Stipple.isreadonly(f, model) || Stipple.isprivate(f, model) || - ! hasproperty(stored_model, f) || ! hasproperty(model, f) || (field[!] = getfield(stored_model, f)[]) - ) + if isnothing(stored_model) || f ∈ [Stipple.CHANNELFIELDNAME, Stipple.AUTOFIELDS...] || + Stipple.isprivate(f, model) || ! hasproperty(stored_model, f) || ! hasproperty(model, f) + else + # restore field value from stored model + (field[!] = getfield(stored_model, f)[]) + end # register reactive handlers to automatically save model on session when model changes if f ∉ [Stipple.AUTOFIELDS...] @@ -40,7 +45,8 @@ function init_from_storage( t::Type{M}; end end else - isnothing(stored_model) || Stipple.isprivate(f, model) || Stipple.isreadonly(f, model) || ! hasproperty(stored_model, f) || ! hasproperty(model, f) || setfield!(model, f, getfield(stored_model, f)) + isnothing(stored_model) || Stipple.isprivate(f, model) || Stipple.isreadonly(f, model) || + ! hasproperty(stored_model, f) || ! hasproperty(model, f) || setfield!(model, f, getfield(stored_model, f)) end end diff --git a/src/ReactiveTools.jl b/src/ReactiveTools.jl index 1456a57a..b38a93f1 100644 --- a/src/ReactiveTools.jl +++ b/src/ReactiveTools.jl @@ -42,7 +42,8 @@ const TYPES = LittleDict{Module,Union{<:DataType,Nothing}}() const HANDLERS_FUNCTIONS = LittleDict{Type{<:ReactiveModel},Function}() function DEFAULT_LAYOUT(; title::String = "Genie App", - meta::D = Dict(), head_content::Union{AbstractString, Vector} = "") where {D <:AbstractDict} + meta::D = Dict(), + head_content::Union{AbstractString, Vector} = "") where {D <:AbstractDict} tags = Genie.Renderers.Html.for_each(x -> """\n""", meta) """ @@ -52,8 +53,8 @@ function DEFAULT_LAYOUT(; title::String = "Genie App", $tags <% Stipple.sesstoken() %> $title - <% if isfile(joinpath(Genie.config.server_document_root, "css", "genieapp.css")) %> - + <% if isfile(joinpath(Stipple.Genie.config.server_document_root, "css", "genieapp.css")) %> + <% else %> <% end %>