package ajax import ( "encoding/json" "errors" "fmt" "local/todo-server/server/ajax/form" "local/todo-server/server/ajax/task" "net/http" "sort" "strconv" "strings" ) type taskWithDelta struct { task *task.Task delta int } func (a *Ajax) loadTasks(w http.ResponseWriter, r *http.Request) error { listID, _, _ := a.Cur(r) filterComplete := filterComplete(form.Get(r, "compl")) filterTags := filterTags(form.ToStrArr(form.Get(r, "t"))) filterSubstr := filterSubstr(form.Get(r, "s")) tasks, err := a.storageListTasks(listID, filterComplete, filterTags, filterSubstr) if err != nil { return err } return json.NewEncoder(w).Encode(map[string]interface{}{"list": tasks}) } func filterComplete(compl string) func(t *task.Task) bool { return func(t *task.Task) bool { return compl == "" || !t.Complete || (compl == "1" && t.Complete) } } func filterTags(tags []string) func(t *task.Task) bool { return func(t *task.Task) bool { for _, whitelisted := range tags { found := false for _, tag := range t.Tags { if whitelisted == tag { found = true } } if !found { return false } } return true } } func filterSubstr(substr string) func(t *task.Task) bool { return func(t *task.Task) bool { return substr == "" || strings.Contains(fmt.Sprintf("%+v", t), substr) } } func (a *Ajax) newTask(w http.ResponseWriter, r *http.Request) error { listID, newTask, err := a.makeTask(r) if err != nil { return err } if err := a.storageSetTask(listID, newTask); err != nil { return err } return json.NewEncoder(w).Encode(map[string]interface{}{ "total": 1, "list": []*task.Task{newTask}, }) } func (a *Ajax) makeTask(r *http.Request) (string, *task.Task, error) { listID, _, tags := a.Cur(r) task, err := task.New(r) if err != nil { return "", nil, err } list, err := a.storageGetList(listID) if err != nil { return "", nil, err } task.Index = list.NextIndex() if err := a.storageSetList(list); err != nil { return "", nil, err } task.AppendTags(tags) return listID, task, nil } func (a *Ajax) deleteTask(w http.ResponseWriter, r *http.Request) error { _, taskID, _ := a.Cur(r) return a.storageDelTask(taskID) } func (a *Ajax) completeTask(w http.ResponseWriter, r *http.Request) error { listID, taskID, _ := a.Cur(r) completedTask, err := a.storageGetTask(taskID) if err != nil { return err } if err := a.storageDelTask(completedTask.UUID); err != nil { return err } completedTask.SetComplete(form.Get(r, "compl") == "1") if err := a.storageSetTask(listID, completedTask); err != nil { return err } return json.NewEncoder(w).Encode(map[string]interface{}{ "total": 1, "list": []*task.Task{completedTask}, }) } func (a *Ajax) editNote(w http.ResponseWriter, r *http.Request) error { listID, taskID, _ := a.Cur(r) task, err := a.storageGetTask(taskID) if err != nil { return err } task.SetNote(form.Get(r, "note")) return a.storageSetTask(listID, task) } func (a *Ajax) editTask(w http.ResponseWriter, r *http.Request) error { listID, task, err := a.makeTask(r) if err != nil { return err } _, taskID, _ := a.Cur(r) task.UUID = taskID return a.storageSetTask(listID, task) } func (a *Ajax) setPrio(w http.ResponseWriter, r *http.Request) error { listID, taskID, _ := a.Cur(r) task, err := a.storageGetTask(taskID) if err != nil { return err } task.SetPrio(form.ToInt(form.Get(r, "prio"))) return a.storageSetTask(listID, task) } func (a *Ajax) moveTask(w http.ResponseWriter, r *http.Request) error { _, taskID, _ := a.Cur(r) toList := form.Get(r, "to") task, err := a.storageGetTask(taskID) if err != nil { return err } if err := a.storageDelTask(taskID); err != nil { return err } return a.storageSetTask(toList, task) } func (a *Ajax) parseTaskStr(w http.ResponseWriter, r *http.Request) error { return errors.New("not impl") } func (a *Ajax) changeOrder(w http.ResponseWriter, r *http.Request) error { order := form.Get(r, "order") orders := strings.Split(order, "&") modified := make([]taskWithDelta, 0) indices := make([]int, 0) for _, order := range orders { taskIDDelta := strings.Split(order, "=") if len(taskIDDelta) < 2 { continue } taskID := taskIDDelta[0] delta, _ := strconv.Atoi(taskIDDelta[1]) task, err := a.storageGetTask(taskID) if err != nil { return err } modified = append(modified, taskWithDelta{task: task, delta: delta}) indices = append(indices, task.Index) } sort.Slice(modified, func(i, j int) bool { if modified[i].delta < modified[j].delta { return true } else if modified[i].delta > modified[j].delta { return false } return modified[i].task.Index < modified[j].task.Index }) sort.Ints(indices) for i := 0; i < len(modified); i++ { task := *modified[i].task task.Index = indices[i] listID, err := a.taskIDToListID(task.UUID) if err != nil { return err } if err := a.storageSetTask(listID, &task); err != nil { return err } } fmt.Fprintf(w, `{"total":1}`) return nil }