feat(explorer): save user's view setting to server / optionally share view setting via share link (#2232)
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -300,6 +300,7 @@ var (
|
||||
{Name: "downloads", Type: field.TypeInt, Default: 0},
|
||||
{Name: "expires", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"mysql": "datetime"}},
|
||||
{Name: "remain_downloads", Type: field.TypeInt, Nullable: true},
|
||||
{Name: "props", Type: field.TypeJSON, Nullable: true},
|
||||
{Name: "file_shares", Type: field.TypeInt, Nullable: true},
|
||||
{Name: "user_shares", Type: field.TypeInt, Nullable: true},
|
||||
}
|
||||
@@ -311,13 +312,13 @@ var (
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "shares_files_shares",
|
||||
Columns: []*schema.Column{SharesColumns[9]},
|
||||
Columns: []*schema.Column{SharesColumns[10]},
|
||||
RefColumns: []*schema.Column{FilesColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
{
|
||||
Symbol: "shares_users_shares",
|
||||
Columns: []*schema.Column{SharesColumns[10]},
|
||||
Columns: []*schema.Column{SharesColumns[11]},
|
||||
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
|
||||
@@ -8958,6 +8958,7 @@ type ShareMutation struct {
|
||||
expires *time.Time
|
||||
remain_downloads *int
|
||||
addremain_downloads *int
|
||||
props **types.ShareProps
|
||||
clearedFields map[string]struct{}
|
||||
user *int
|
||||
cleareduser bool
|
||||
@@ -9467,6 +9468,55 @@ func (m *ShareMutation) ResetRemainDownloads() {
|
||||
delete(m.clearedFields, share.FieldRemainDownloads)
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (m *ShareMutation) SetProps(tp *types.ShareProps) {
|
||||
m.props = &tp
|
||||
}
|
||||
|
||||
// Props returns the value of the "props" field in the mutation.
|
||||
func (m *ShareMutation) Props() (r *types.ShareProps, exists bool) {
|
||||
v := m.props
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldProps returns the old "props" field's value of the Share entity.
|
||||
// If the Share object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *ShareMutation) OldProps(ctx context.Context) (v *types.ShareProps, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldProps is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldProps requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldProps: %w", err)
|
||||
}
|
||||
return oldValue.Props, nil
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (m *ShareMutation) ClearProps() {
|
||||
m.props = nil
|
||||
m.clearedFields[share.FieldProps] = struct{}{}
|
||||
}
|
||||
|
||||
// PropsCleared returns if the "props" field was cleared in this mutation.
|
||||
func (m *ShareMutation) PropsCleared() bool {
|
||||
_, ok := m.clearedFields[share.FieldProps]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetProps resets all changes to the "props" field.
|
||||
func (m *ShareMutation) ResetProps() {
|
||||
m.props = nil
|
||||
delete(m.clearedFields, share.FieldProps)
|
||||
}
|
||||
|
||||
// SetUserID sets the "user" edge to the User entity by id.
|
||||
func (m *ShareMutation) SetUserID(id int) {
|
||||
m.user = &id
|
||||
@@ -9579,7 +9629,7 @@ func (m *ShareMutation) Type() string {
|
||||
// order to get all numeric fields that were incremented/decremented, call
|
||||
// AddedFields().
|
||||
func (m *ShareMutation) Fields() []string {
|
||||
fields := make([]string, 0, 8)
|
||||
fields := make([]string, 0, 9)
|
||||
if m.created_at != nil {
|
||||
fields = append(fields, share.FieldCreatedAt)
|
||||
}
|
||||
@@ -9604,6 +9654,9 @@ func (m *ShareMutation) Fields() []string {
|
||||
if m.remain_downloads != nil {
|
||||
fields = append(fields, share.FieldRemainDownloads)
|
||||
}
|
||||
if m.props != nil {
|
||||
fields = append(fields, share.FieldProps)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
@@ -9628,6 +9681,8 @@ func (m *ShareMutation) Field(name string) (ent.Value, bool) {
|
||||
return m.Expires()
|
||||
case share.FieldRemainDownloads:
|
||||
return m.RemainDownloads()
|
||||
case share.FieldProps:
|
||||
return m.Props()
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
@@ -9653,6 +9708,8 @@ func (m *ShareMutation) OldField(ctx context.Context, name string) (ent.Value, e
|
||||
return m.OldExpires(ctx)
|
||||
case share.FieldRemainDownloads:
|
||||
return m.OldRemainDownloads(ctx)
|
||||
case share.FieldProps:
|
||||
return m.OldProps(ctx)
|
||||
}
|
||||
return nil, fmt.Errorf("unknown Share field %s", name)
|
||||
}
|
||||
@@ -9718,6 +9775,13 @@ func (m *ShareMutation) SetField(name string, value ent.Value) error {
|
||||
}
|
||||
m.SetRemainDownloads(v)
|
||||
return nil
|
||||
case share.FieldProps:
|
||||
v, ok := value.(*types.ShareProps)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetProps(v)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown Share field %s", name)
|
||||
}
|
||||
@@ -9799,6 +9863,9 @@ func (m *ShareMutation) ClearedFields() []string {
|
||||
if m.FieldCleared(share.FieldRemainDownloads) {
|
||||
fields = append(fields, share.FieldRemainDownloads)
|
||||
}
|
||||
if m.FieldCleared(share.FieldProps) {
|
||||
fields = append(fields, share.FieldProps)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
@@ -9825,6 +9892,9 @@ func (m *ShareMutation) ClearField(name string) error {
|
||||
case share.FieldRemainDownloads:
|
||||
m.ClearRemainDownloads()
|
||||
return nil
|
||||
case share.FieldProps:
|
||||
m.ClearProps()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown Share nullable field %s", name)
|
||||
}
|
||||
@@ -9857,6 +9927,9 @@ func (m *ShareMutation) ResetField(name string) error {
|
||||
case share.FieldRemainDownloads:
|
||||
m.ResetRemainDownloads()
|
||||
return nil
|
||||
case share.FieldProps:
|
||||
m.ResetProps()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown Share field %s", name)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
)
|
||||
|
||||
// Share holds the schema definition for the Share entity.
|
||||
@@ -30,6 +31,7 @@ func (Share) Fields() []ent.Field {
|
||||
field.Int("remain_downloads").
|
||||
Nillable().
|
||||
Optional(),
|
||||
field.JSON("props", &types.ShareProps{}).Optional(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
17
ent/share.go
17
ent/share.go
@@ -3,6 +3,7 @@
|
||||
package ent
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/share"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
)
|
||||
|
||||
// Share is the model entity for the Share schema.
|
||||
@@ -35,6 +37,8 @@ type Share struct {
|
||||
Expires *time.Time `json:"expires,omitempty"`
|
||||
// RemainDownloads holds the value of the "remain_downloads" field.
|
||||
RemainDownloads *int `json:"remain_downloads,omitempty"`
|
||||
// Props holds the value of the "props" field.
|
||||
Props *types.ShareProps `json:"props,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the ShareQuery when eager-loading is set.
|
||||
Edges ShareEdges `json:"edges"`
|
||||
@@ -85,6 +89,8 @@ func (*Share) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case share.FieldProps:
|
||||
values[i] = new([]byte)
|
||||
case share.FieldID, share.FieldViews, share.FieldDownloads, share.FieldRemainDownloads:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case share.FieldPassword:
|
||||
@@ -167,6 +173,14 @@ func (s *Share) assignValues(columns []string, values []any) error {
|
||||
s.RemainDownloads = new(int)
|
||||
*s.RemainDownloads = int(value.Int64)
|
||||
}
|
||||
case share.FieldProps:
|
||||
if value, ok := values[i].(*[]byte); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field props", values[i])
|
||||
} else if value != nil && len(*value) > 0 {
|
||||
if err := json.Unmarshal(*value, &s.Props); err != nil {
|
||||
return fmt.Errorf("unmarshal field props: %w", err)
|
||||
}
|
||||
}
|
||||
case share.ForeignKeys[0]:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for edge-field file_shares", value)
|
||||
@@ -256,6 +270,9 @@ func (s *Share) String() string {
|
||||
builder.WriteString("remain_downloads=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("props=")
|
||||
builder.WriteString(fmt.Sprintf("%v", s.Props))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ const (
|
||||
FieldExpires = "expires"
|
||||
// FieldRemainDownloads holds the string denoting the remain_downloads field in the database.
|
||||
FieldRemainDownloads = "remain_downloads"
|
||||
// FieldProps holds the string denoting the props field in the database.
|
||||
FieldProps = "props"
|
||||
// EdgeUser holds the string denoting the user edge name in mutations.
|
||||
EdgeUser = "user"
|
||||
// EdgeFile holds the string denoting the file edge name in mutations.
|
||||
@@ -64,6 +66,7 @@ var Columns = []string{
|
||||
FieldDownloads,
|
||||
FieldExpires,
|
||||
FieldRemainDownloads,
|
||||
FieldProps,
|
||||
}
|
||||
|
||||
// ForeignKeys holds the SQL foreign-keys that are owned by the "shares"
|
||||
|
||||
@@ -480,6 +480,16 @@ func RemainDownloadsNotNil() predicate.Share {
|
||||
return predicate.Share(sql.FieldNotNull(FieldRemainDownloads))
|
||||
}
|
||||
|
||||
// PropsIsNil applies the IsNil predicate on the "props" field.
|
||||
func PropsIsNil() predicate.Share {
|
||||
return predicate.Share(sql.FieldIsNull(FieldProps))
|
||||
}
|
||||
|
||||
// PropsNotNil applies the NotNil predicate on the "props" field.
|
||||
func PropsNotNil() predicate.Share {
|
||||
return predicate.Share(sql.FieldNotNull(FieldProps))
|
||||
}
|
||||
|
||||
// HasUser applies the HasEdge predicate on the "user" edge.
|
||||
func HasUser() predicate.Share {
|
||||
return predicate.Share(func(s *sql.Selector) {
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/share"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
)
|
||||
|
||||
// ShareCreate is the builder for creating a Share entity.
|
||||
@@ -136,6 +137,12 @@ func (sc *ShareCreate) SetNillableRemainDownloads(i *int) *ShareCreate {
|
||||
return sc
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (sc *ShareCreate) SetProps(tp *types.ShareProps) *ShareCreate {
|
||||
sc.mutation.SetProps(tp)
|
||||
return sc
|
||||
}
|
||||
|
||||
// SetUserID sets the "user" edge to the User entity by ID.
|
||||
func (sc *ShareCreate) SetUserID(id int) *ShareCreate {
|
||||
sc.mutation.SetUserID(id)
|
||||
@@ -316,6 +323,10 @@ func (sc *ShareCreate) createSpec() (*Share, *sqlgraph.CreateSpec) {
|
||||
_spec.SetField(share.FieldRemainDownloads, field.TypeInt, value)
|
||||
_node.RemainDownloads = &value
|
||||
}
|
||||
if value, ok := sc.mutation.Props(); ok {
|
||||
_spec.SetField(share.FieldProps, field.TypeJSON, value)
|
||||
_node.Props = value
|
||||
}
|
||||
if nodes := sc.mutation.UserIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
@@ -528,6 +539,24 @@ func (u *ShareUpsert) ClearRemainDownloads() *ShareUpsert {
|
||||
return u
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (u *ShareUpsert) SetProps(v *types.ShareProps) *ShareUpsert {
|
||||
u.Set(share.FieldProps, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateProps sets the "props" field to the value that was provided on create.
|
||||
func (u *ShareUpsert) UpdateProps() *ShareUpsert {
|
||||
u.SetExcluded(share.FieldProps)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (u *ShareUpsert) ClearProps() *ShareUpsert {
|
||||
u.SetNull(share.FieldProps)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that were set on create.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
@@ -720,6 +749,27 @@ func (u *ShareUpsertOne) ClearRemainDownloads() *ShareUpsertOne {
|
||||
})
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (u *ShareUpsertOne) SetProps(v *types.ShareProps) *ShareUpsertOne {
|
||||
return u.Update(func(s *ShareUpsert) {
|
||||
s.SetProps(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateProps sets the "props" field to the value that was provided on create.
|
||||
func (u *ShareUpsertOne) UpdateProps() *ShareUpsertOne {
|
||||
return u.Update(func(s *ShareUpsert) {
|
||||
s.UpdateProps()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (u *ShareUpsertOne) ClearProps() *ShareUpsertOne {
|
||||
return u.Update(func(s *ShareUpsert) {
|
||||
s.ClearProps()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *ShareUpsertOne) Exec(ctx context.Context) error {
|
||||
if len(u.create.conflict) == 0 {
|
||||
@@ -1083,6 +1133,27 @@ func (u *ShareUpsertBulk) ClearRemainDownloads() *ShareUpsertBulk {
|
||||
})
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (u *ShareUpsertBulk) SetProps(v *types.ShareProps) *ShareUpsertBulk {
|
||||
return u.Update(func(s *ShareUpsert) {
|
||||
s.SetProps(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateProps sets the "props" field to the value that was provided on create.
|
||||
func (u *ShareUpsertBulk) UpdateProps() *ShareUpsertBulk {
|
||||
return u.Update(func(s *ShareUpsert) {
|
||||
s.UpdateProps()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (u *ShareUpsertBulk) ClearProps() *ShareUpsertBulk {
|
||||
return u.Update(func(s *ShareUpsert) {
|
||||
s.ClearProps()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *ShareUpsertBulk) Exec(ctx context.Context) error {
|
||||
if u.create.err != nil {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/share"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
)
|
||||
|
||||
// ShareUpdate is the builder for updating Share entities.
|
||||
@@ -165,6 +166,18 @@ func (su *ShareUpdate) ClearRemainDownloads() *ShareUpdate {
|
||||
return su
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (su *ShareUpdate) SetProps(tp *types.ShareProps) *ShareUpdate {
|
||||
su.mutation.SetProps(tp)
|
||||
return su
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (su *ShareUpdate) ClearProps() *ShareUpdate {
|
||||
su.mutation.ClearProps()
|
||||
return su
|
||||
}
|
||||
|
||||
// SetUserID sets the "user" edge to the User entity by ID.
|
||||
func (su *ShareUpdate) SetUserID(id int) *ShareUpdate {
|
||||
su.mutation.SetUserID(id)
|
||||
@@ -313,6 +326,12 @@ func (su *ShareUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if su.mutation.RemainDownloadsCleared() {
|
||||
_spec.ClearField(share.FieldRemainDownloads, field.TypeInt)
|
||||
}
|
||||
if value, ok := su.mutation.Props(); ok {
|
||||
_spec.SetField(share.FieldProps, field.TypeJSON, value)
|
||||
}
|
||||
if su.mutation.PropsCleared() {
|
||||
_spec.ClearField(share.FieldProps, field.TypeJSON)
|
||||
}
|
||||
if su.mutation.UserCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
@@ -526,6 +545,18 @@ func (suo *ShareUpdateOne) ClearRemainDownloads() *ShareUpdateOne {
|
||||
return suo
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (suo *ShareUpdateOne) SetProps(tp *types.ShareProps) *ShareUpdateOne {
|
||||
suo.mutation.SetProps(tp)
|
||||
return suo
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (suo *ShareUpdateOne) ClearProps() *ShareUpdateOne {
|
||||
suo.mutation.ClearProps()
|
||||
return suo
|
||||
}
|
||||
|
||||
// SetUserID sets the "user" edge to the User entity by ID.
|
||||
func (suo *ShareUpdateOne) SetUserID(id int) *ShareUpdateOne {
|
||||
suo.mutation.SetUserID(id)
|
||||
@@ -704,6 +735,12 @@ func (suo *ShareUpdateOne) sqlSave(ctx context.Context) (_node *Share, err error
|
||||
if suo.mutation.RemainDownloadsCleared() {
|
||||
_spec.ClearField(share.FieldRemainDownloads, field.TypeInt)
|
||||
}
|
||||
if value, ok := suo.mutation.Props(); ok {
|
||||
_spec.SetField(share.FieldProps, field.TypeJSON, value)
|
||||
}
|
||||
if suo.mutation.PropsCleared() {
|
||||
_spec.ClearField(share.FieldProps, field.TypeJSON)
|
||||
}
|
||||
if suo.mutation.UserCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
|
||||
Reference in New Issue
Block a user