mirror of
				https://github.com/nkanaev/yarr.git
				synced 2025-11-04 00:38:46 +00:00 
			
		
		
		
	Compare commits
	
		
			6 Commits
		
	
	
		
			96835ebd33
			...
			4983e18e23
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					4983e18e23 | ||
| 
						 | 
					e1954e4cba | ||
| 
						 | 
					58420ae52b | ||
| 
						 | 
					b01f71de1a | ||
| 
						 | 
					379aaed39e | ||
| 
						 | 
					dc20932060 | 
@@ -1,11 +1,13 @@
 | 
				
			|||||||
# upcoming 
 | 
					# upcoming 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- (new) Fever API support (thanks to @icefed)
 | 
					- (new) Fever API support (thanks to @icefed)
 | 
				
			||||||
 | 
					- (new) editable feed link (thanks to @adaszko)
 | 
				
			||||||
- (fix) duplicate articles caused by the same feed addition (thanks to @adaszko)
 | 
					- (fix) duplicate articles caused by the same feed addition (thanks to @adaszko)
 | 
				
			||||||
- (fix) relative article links (thanks to @adazsko for the report)
 | 
					- (fix) relative article links (thanks to @adazsko for the report)
 | 
				
			||||||
- (fix) atom article links stored in id element (thanks to @adazsko for the report)
 | 
					- (fix) atom article links stored in id element (thanks to @adazsko for the report)
 | 
				
			||||||
- (fix) parsing atom feed titles (thanks to @wnh)
 | 
					- (fix) parsing atom feed titles (thanks to @wnh)
 | 
				
			||||||
- (fix) sorting same-day batch articles (thanks to @lamescholar for the report)
 | 
					- (fix) sorting same-day batch articles (thanks to @lamescholar for the report)
 | 
				
			||||||
 | 
					- (fix) showing login page in the selected theme (thanks to @feddiriko for the report)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# v2.4 (2023-08-15)
 | 
					# v2.4 (2023-08-15)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -220,6 +220,10 @@
 | 
				
			|||||||
                        <span class="icon mr-1">{% inline "edit.svg" %}</span>
 | 
					                        <span class="icon mr-1">{% inline "edit.svg" %}</span>
 | 
				
			||||||
                        Rename
 | 
					                        Rename
 | 
				
			||||||
                    </button>
 | 
					                    </button>
 | 
				
			||||||
 | 
					                    <button class="dropdown-item" @click="updateFeedLink(current.feed)" v-if="current.feed.feed_link">
 | 
				
			||||||
 | 
					                        <span class="icon mr-1">{% inline "edit.svg" %}</span>
 | 
				
			||||||
 | 
					                        Change Link
 | 
				
			||||||
 | 
					                    </button>
 | 
				
			||||||
                    <div class="dropdown-divider"></div>
 | 
					                    <div class="dropdown-divider"></div>
 | 
				
			||||||
                    <header class="dropdown-header">Move to...</header>
 | 
					                    <header class="dropdown-header">Move to...</header>
 | 
				
			||||||
                    <button class="dropdown-item"
 | 
					                    <button class="dropdown-item"
 | 
				
			||||||
@@ -338,7 +342,11 @@
 | 
				
			|||||||
                <div class="content-wrapper">
 | 
					                <div class="content-wrapper">
 | 
				
			||||||
                    <h1><b>{{ itemSelectedDetails.title || 'untitled' }}</b></h1>
 | 
					                    <h1><b>{{ itemSelectedDetails.title || 'untitled' }}</b></h1>
 | 
				
			||||||
                    <div class="text-muted">
 | 
					                    <div class="text-muted">
 | 
				
			||||||
                        <div>{{ (feedsById[itemSelectedDetails.feed_id] || {}).title }}</div>
 | 
					                        <div>
 | 
				
			||||||
 | 
					                            <span class="cursor-pointer" @click="feedSelected = 'feed:'+(feedsById[itemSelectedDetails.feed_id] || {}).id">
 | 
				
			||||||
 | 
					                                {{ (feedsById[itemSelectedDetails.feed_id] || {}).title }}
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
                        <time>{{ formatDate(itemSelectedDetails.date) }}</time>
 | 
					                        <time>{{ formatDate(itemSelectedDetails.date) }}</time>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                    <hr>
 | 
					                    <hr>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -523,6 +523,14 @@ var vm = new Vue({
 | 
				
			|||||||
        })
 | 
					        })
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    updateFeedLink: function(feed) {
 | 
				
			||||||
 | 
					      var newLink = prompt('Enter feed link', feed.feed_link)
 | 
				
			||||||
 | 
					      if (newLink) {
 | 
				
			||||||
 | 
					        api.feeds.update(feed.id, {feed_link: newLink}).then(function() {
 | 
				
			||||||
 | 
					          feed.feed_link = newLink
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    renameFeed: function(feed) {
 | 
					    renameFeed: function(feed) {
 | 
				
			||||||
      var newTitle = prompt('Enter new title', feed.title)
 | 
					      var newTitle = prompt('Enter new title', feed.title)
 | 
				
			||||||
      if (newTitle) {
 | 
					      if (newTitle) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    </style>
 | 
					    </style>
 | 
				
			||||||
</head>
 | 
					</head>
 | 
				
			||||||
<body>
 | 
					<body class="theme-{% .settings.theme_name %}">
 | 
				
			||||||
    <form action="" method="post">
 | 
					    <form action="" method="post">
 | 
				
			||||||
        <img src="./static/graphicarts/anchor.svg" alt="">
 | 
					        <img src="./static/graphicarts/anchor.svg" alt="">
 | 
				
			||||||
        {% if .error %}
 | 
					        {% if .error %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/nkanaev/yarr/src/assets"
 | 
						"github.com/nkanaev/yarr/src/assets"
 | 
				
			||||||
	"github.com/nkanaev/yarr/src/server/router"
 | 
						"github.com/nkanaev/yarr/src/server/router"
 | 
				
			||||||
 | 
						"github.com/nkanaev/yarr/src/storage"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Middleware struct {
 | 
					type Middleware struct {
 | 
				
			||||||
@@ -13,6 +14,7 @@ type Middleware struct {
 | 
				
			|||||||
	Password string
 | 
						Password string
 | 
				
			||||||
	BasePath string
 | 
						BasePath string
 | 
				
			||||||
	Public   []string
 | 
						Public   []string
 | 
				
			||||||
 | 
						DB       *storage.Storage
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func unsafeMethod(method string) bool {
 | 
					func unsafeMethod(method string) bool {
 | 
				
			||||||
@@ -46,12 +48,15 @@ func (m *Middleware) Handler(c *router.Context) {
 | 
				
			|||||||
			c.Redirect(rootUrl)
 | 
								c.Redirect(rootUrl)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			c.HTML(http.StatusOK, assets.Template("login.html"), map[string]string{
 | 
								c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{
 | 
				
			||||||
				"username": username,
 | 
									"username": username,
 | 
				
			||||||
				"error":    "Invalid username/password",
 | 
									"error":    "Invalid username/password",
 | 
				
			||||||
 | 
							        "settings": m.DB.GetSettings(),
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c.HTML(http.StatusOK, assets.Template("login.html"), nil)
 | 
						c.HTML(http.StatusOK, assets.Template("login.html"), map[string]interface{}{
 | 
				
			||||||
 | 
					        "settings": m.DB.GetSettings(),
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,6 +35,7 @@ func (s *Server) handler() http.Handler {
 | 
				
			|||||||
			Username: s.Username,
 | 
								Username: s.Username,
 | 
				
			||||||
			Password: s.Password,
 | 
								Password: s.Password,
 | 
				
			||||||
			Public:   []string{"/static", "/fever"},
 | 
								Public:   []string{"/static", "/fever"},
 | 
				
			||||||
 | 
					            DB:       s.db,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		r.Use(a.Handler)
 | 
							r.Use(a.Handler)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -293,6 +294,11 @@ func (s *Server) handleFeed(c *router.Context) {
 | 
				
			|||||||
				s.db.UpdateFeedFolder(id, &folderId)
 | 
									s.db.UpdateFeedFolder(id, &folderId)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if link, ok := body["feed_link"]; ok {
 | 
				
			||||||
 | 
								if reflect.TypeOf(link).Kind() == reflect.String {
 | 
				
			||||||
 | 
									s.db.UpdateFeedLink(id, link.(string))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		c.Out.WriteHeader(http.StatusOK)
 | 
							c.Out.WriteHeader(http.StatusOK)
 | 
				
			||||||
	} else if c.Req.Method == "DELETE" {
 | 
						} else if c.Req.Method == "DELETE" {
 | 
				
			||||||
		s.db.DeleteFeed(id)
 | 
							s.db.DeleteFeed(id)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -71,6 +71,11 @@ func (s *Storage) UpdateFeedFolder(feedId int64, newFolderId *int64) bool {
 | 
				
			|||||||
	return err == nil
 | 
						return err == nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *Storage) UpdateFeedLink(feedId int64, newLink string) bool {
 | 
				
			||||||
 | 
						_, err := s.db.Exec(`update feeds set feed_link = ? where id = ?`, newLink, feedId)
 | 
				
			||||||
 | 
						return err == nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Storage) UpdateFeedIcon(feedId int64, icon *[]byte) bool {
 | 
					func (s *Storage) UpdateFeedIcon(feedId int64, icon *[]byte) bool {
 | 
				
			||||||
	_, err := s.db.Exec(`update feeds set icon = ? where id = ?`, icon, feedId)
 | 
						_, err := s.db.Exec(`update feeds set icon = ? where id = ?`, icon, feedId)
 | 
				
			||||||
	return err == nil
 | 
						return err == nil
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user