diff options
author | Vitaly Takmazov | 2023-04-10 22:53:40 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2023-04-13 19:49:55 +0300 |
commit | 379f1a8661da46040332923a5ccfb555656b0a8b (patch) | |
tree | 12b3d6121d749c4dc942b10c733f77d7d6dbba94 /src | |
parent | 3a1e45d3015df62eb5768a8e6929cb41dcaf9913 (diff) |
Premium users
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/com/juick/model/User.java | 9 | ||||
-rw-r--r-- | src/main/java/com/juick/service/MessagesServiceImpl.java | 8 | ||||
-rw-r--r-- | src/main/java/com/juick/service/UserService.java | 7 | ||||
-rw-r--r-- | src/main/java/com/juick/service/UserServiceImpl.java | 57 | ||||
-rw-r--r-- | src/main/java/com/juick/www/api/ApiSocialLogin.java | 4 | ||||
-rw-r--r-- | src/main/java/com/juick/www/controllers/SocialLogin.java | 46 | ||||
-rw-r--r-- | src/main/resources/db/migration/V1.46__premium_users.sql | 1 | ||||
-rw-r--r-- | src/main/resources/schema-h2.sql | 1 | ||||
-rw-r--r-- | src/main/resources/schema-mysql.sql | 1 | ||||
-rw-r--r-- | src/main/resources/schema-sqlite.sql | 1 | ||||
-rw-r--r-- | src/main/resources/schema-sqlserver.sql | 1 | ||||
-rw-r--r-- | src/main/resources/templates/views/partial/message.html | 2 | ||||
-rw-r--r-- | src/main/resources/templates/views/partial/navigation.html | 3 | ||||
-rw-r--r-- | src/main/resources/templates/views/thread.html | 4 |
14 files changed, 111 insertions, 34 deletions
diff --git a/src/main/java/com/juick/model/User.java b/src/main/java/com/juick/model/User.java index 131ec1b1..5f89ecfc 100644 --- a/src/main/java/com/juick/model/User.java +++ b/src/main/java/com/juick/model/User.java @@ -61,6 +61,7 @@ public class User implements Serializable { private String url; private String description; private final List<TagStats> tagStats; + private boolean premium; public User() { tokens = new ArrayList<>(); @@ -279,4 +280,12 @@ public class User implements Serializable { public List<TagStats> getTagStats() { return tagStats; } + + public boolean isPremium() { + return premium; + } + + public void setPremium(boolean premium) { + this.premium = premium; + } } diff --git a/src/main/java/com/juick/service/MessagesServiceImpl.java b/src/main/java/com/juick/service/MessagesServiceImpl.java index 083524b1..53f2407c 100644 --- a/src/main/java/com/juick/service/MessagesServiceImpl.java +++ b/src/main/java/com/juick/service/MessagesServiceImpl.java @@ -83,6 +83,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ user.setName(Optional.ofNullable(rs.getString(5)).orElse(AnonymousUser.INSTANCE.getName())); user.setBanned(rs.getBoolean(6)); user.setUri(URI.create(Optional.ofNullable(rs.getString(22)).orElse(StringUtils.EMPTY))); + user.setPremium(rs.getInt("premium") > 0); msg.setUser(user); msg.setCreated(MessagesServiceImpl.this.getOffsetDateTime(rs, 7).toInstant()); msg.ReadOnly = rs.getBoolean(8); @@ -797,7 +798,8 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ COALESCE(messages.txt, '') txt, '' as q, messages.updated, 0 as to_uid, NULL as to_name, messages.updated_at, '' as m_user_uri, '' as to_uri, '' as msg_reply_uri, 0 as html, (1.*messages.replies - subscr_messages.last_read_rid) as unread, - (SELECT CASE WHEN EXISTS(SELECT * from subscr_messages where message_id=messages.message_id and suser_id=:uid) THEN 1 ELSE 0 END) subscribed + (SELECT CASE WHEN EXISTS(SELECT * from subscr_messages where message_id=messages.message_id and suser_id=:uid) THEN 1 ELSE 0 END) subscribed, + users.premium FROM messages INNER JOIN users ON messages.user_id=users.id LEFT JOIN subscr_messages ON messages.message_id=subscr_messages.message_id AND subscr_messages.suser_id=:uid LEFT JOIN favorites ON messages.message_id = favorites.message_id AND favorites.like_id=1 @@ -808,7 +810,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ messages.message_id, messages.user_id, users.nick, users.banned, messages.ts, messages.readonly, messages.privacy, messages.attach, messages.hidden, messages.repliesby, messages.txt, messages.updated, messages.replies, updated_at, - subscr_messages.last_read_rid"""; + subscr_messages.last_read_rid, users.premium"""; List<Message> msgs = getNamedParameterJdbcTemplate().query(query, new MapSqlParameterSource("ids", mids) .addValue("uid", uid), new MessageMapper()); @@ -867,7 +869,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ + "COALESCE(qw.user_id, m.user_id) as to_uid, COALESCE(qu.nick, mu.nick) as to_name, " + "replies.updated_at, replies.user_uri as uri, " + "qw.user_uri as to_uri, replies.reply_uri, replies.html, 0 as unread, " - + "0 as subscribed " + + "0 as subscribed, users.premium " + "FROM replies LEFT JOIN users " + "ON replies.user_id = users.id " + "LEFT JOIN replies qw ON replies.message_id = qw.message_id and replies.replyto = qw.reply_id " + "LEFT JOIN messages m on replies.message_id = m.message_id " diff --git a/src/main/java/com/juick/service/UserService.java b/src/main/java/com/juick/service/UserService.java index 05725b73..ec5beb13 100644 --- a/src/main/java/com/juick/service/UserService.java +++ b/src/main/java/com/juick/service/UserService.java @@ -152,7 +152,7 @@ public interface UserService { String getTelegramName(int uid); - Optional<Pair<String, String>> getVkTokens(int uid); + List<Pair<String, String>> getVkTokens(List<Integer> uids); void deleteVKUser(Integer uid); @@ -166,6 +166,9 @@ public interface UserService { boolean createVKUser(long vkID, String loginhash, String token, String vkName, String vkLink); + boolean updateVkUser(long vkID, String token, String vkName, String vkLink); + boolean updateVkToken(long userId, String token); + String getFacebookNameByHash(String hash); String getTelegramNameByHash(String hash); @@ -197,4 +200,6 @@ public interface UserService { boolean addToken(Integer uid, String serviceType, String token); boolean deleteToken(String serviceType, String token); + + void setPremium(Integer uid, boolean isPremium); } diff --git a/src/main/java/com/juick/service/UserServiceImpl.java b/src/main/java/com/juick/service/UserServiceImpl.java index 932be19c..a7ea5c5f 100644 --- a/src/main/java/com/juick/service/UserServiceImpl.java +++ b/src/main/java/com/juick/service/UserServiceImpl.java @@ -65,6 +65,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { user.setSeen(seen.toInstant()); } user.setVerified(rs.getLong(6) > 0); + user.setPremium(rs.getInt(7) > 0); return user; } } @@ -113,7 +114,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { public Optional<User> getUserByUID(final int uid) { var list = getJdbcTemplate().query(""" SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen, - COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified + COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium FROM users u LEFT JOIN facebook f ON f.user_id = u.id LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id LEFT JOIN emails e ON e.user_id = u.id WHERE u.id = ?""", new UserMapper(), uid); @@ -127,7 +128,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { if (StringUtils.isNotBlank(username)) { var list = getJdbcTemplate().query(""" SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen, - COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified + COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium FROM users u LEFT JOIN facebook f ON f.user_id = u.id LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id LEFT JOIN emails e ON e.user_id = u.id @@ -152,7 +153,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { try { List<User> list = getJdbcTemplate().query( "SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen, " + - "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified " + + "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium " + "FROM users u LEFT JOIN facebook f ON f.user_id = u.id " + "LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id " + "LEFT JOIN emails e ON e.user_id = u.id " + @@ -178,7 +179,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { if (StringUtils.isNotBlank(jid)) { List<User> list = getJdbcTemplate().query( "SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen," + - "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified " + + "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium " + "FROM users u LEFT JOIN facebook f ON f.user_id = u.id " + "LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id " + "LEFT JOIN emails e ON e.user_id = u.id " + @@ -200,7 +201,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { return getNamedParameterJdbcTemplate().query( "SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen," + - "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified " + + "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium " + "FROM users u LEFT JOIN facebook f ON f.user_id = u.id " + "LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id " + "LEFT JOIN emails e ON e.user_id = u.id " + @@ -217,7 +218,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { return getNamedParameterJdbcTemplate().query( "SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen," + - "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified " + + "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium " + "FROM users u LEFT JOIN facebook f ON f.user_id = u.id " + "LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id " + "LEFT JOIN emails e ON e.user_id = u.id " + @@ -252,7 +253,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { if (StringUtils.isNotBlank(hash)) { List<User> list = getJdbcTemplate().query( "SELECT DISTINCT logins.user_id, u.nick, u.passw, u.banned, u.last_seen," + - "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified " + + "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium " + "FROM logins INNER JOIN users u ON logins.user_id = u.id " + "LEFT JOIN facebook f ON f.user_id = u.id " + "LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id " + @@ -290,7 +291,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { if (StringUtils.isNotBlank(username)) { List<User> list = getJdbcTemplate().query( "SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen," + - "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified " + + "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium " + "FROM users u LEFT JOIN facebook f ON f.user_id = u.id " + "LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id " + "LEFT JOIN emails e ON e.user_id = u.id " + @@ -719,7 +720,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { List<User> list = getJdbcTemplate().query( """ SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen, - COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified + COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium FROM users u LEFT JOIN facebook f ON f.user_id = u.id LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id LEFT JOIN emails e ON e.user_id = u.id @@ -732,14 +733,14 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { @Transactional(readOnly = true) @Override - public Optional<Pair<String, String>> getVkTokens(final int uid) { - List<Optional<Pair<String, String>>> list = getJdbcTemplate().query( - "SELECT vk_id, access_token FROM vk WHERE user_id = ? AND crosspost = 1", - (rs, num) -> Optional.of(Pair.of(rs.getString(1), rs.getString(2))), - uid); - - return list.isEmpty() ? - Optional.empty() : list.get(0); + public List<Pair<String, String>> getVkTokens(List<Integer> uids) { + return getNamedParameterJdbcTemplate().query( + """ + SELECT vk_id, access_token FROM vk WHERE crosspost = 1 AND access_token <> ''""" + + (uids.isEmpty() ? "" : " AND user_id IN (:uids)"), + new MapSqlParameterSource() + .addValue("uids", uids), + (rs, num) -> Pair.of(rs.getString(1), rs.getString(2))); } @Transactional @@ -753,7 +754,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { public Optional<User> getUserByFacebookId(long facebookId) { List<User> list = getJdbcTemplate().query( "SELECT DISTINCT u.id, u.nick, u.passw, u.banned, u.last_seen, " + - "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified " + + "COALESCE(f.fb_id, vk.vk_id, t.tg_id, e.user_id, 0) AS verified, premium " + "FROM users u LEFT JOIN facebook f ON f.user_id = u.id " + "LEFT JOIN vk ON u.id = vk.user_id LEFT JOIN telegram t ON u.id = t.user_id " + "LEFT JOIN emails e ON e.user_id = u.id WHERE f.fb_id = ?", new UserMapper(), facebookId); @@ -789,6 +790,18 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { return getJdbcTemplate().update("INSERT INTO vk(vk_id,loginhash,access_token,vk_name,vk_link) VALUES (?,?,?,?,?)", vkID, loginhash, token, vkName, vkLink) > 0; } + @Transactional + @Override + public boolean updateVkUser(long vkID, String token, String vkName, String vkLink) { + return getJdbcTemplate().update("UPDATE vk SET access_token=?,vk_name=?,vk_link=? WHERE vk_id=?", + token, vkName, vkLink, vkID) > 0; + } + @Transactional + @Override + public boolean updateVkToken(long userId, String token) { + return getJdbcTemplate().update("UPDATE vk SET access_token=? WHERE user_id=?", + token, userId) > 0; + } @Transactional(readOnly = true) @Override @@ -864,7 +877,7 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { @Transactional(readOnly = true) @Override public boolean canDeleteTelegramUser(User user) { - return getEmails(user).size() > 0 || getFbCrossPostStatus(user.getUid()).isConnected() || getVkTokens(user.getUid()).isPresent(); + return getEmails(user).size() > 0 || getFbCrossPostStatus(user.getUid()).isConnected() || !getVkTokens(List.of(user.getUid())).isEmpty(); } private static class TokenMapper implements RowMapper<ExternalToken> { @@ -918,5 +931,11 @@ public class UserServiceImpl extends BaseJdbcService implements UserService { public boolean deleteToken(final String serviceType, final String token) { return getJdbcTemplate().update("DELETE FROM user_services WHERE regid=? AND service_type=?", token, serviceType) > 0; } + + @Transactional + @Override + public void setPremium(final Integer uid, boolean isPremium) { + getJdbcTemplate().update("UPDATE users SET premium=? WHERE id=?", isPremium ? 1 : 0, uid); + } } diff --git a/src/main/java/com/juick/www/api/ApiSocialLogin.java b/src/main/java/com/juick/www/api/ApiSocialLogin.java index a05e33d9..bf0d26bc 100644 --- a/src/main/java/com/juick/www/api/ApiSocialLogin.java +++ b/src/main/java/com/juick/www/api/ApiSocialLogin.java @@ -113,7 +113,7 @@ public class ApiSocialLogin { .build(FacebookApi.instance()); vkAuthService = vkBuilder .apiSecret(VK_SECRET) - .defaultScope("friends,wall,offline") + .defaultScope("friends,wall,offline,groups") .callback(VK_REDIRECT) .build(VkontakteApi.instance()); ServiceBuilder appleSignInBuilder = new ServiceBuilder(appleApplicationId); @@ -195,7 +195,7 @@ public class ApiSocialLogin { } OAuth2AccessToken token = vkAuthService.getAccessToken(code); - OAuthRequest meRequest = new OAuthRequest(Verb.GET, "https://api.vk.com/method/users.get?fields=screen_name&v=5.73"); + OAuthRequest meRequest = new OAuthRequest(Verb.GET, "https://api.vk.com/method/users.get?fields=screen_name&v=5.131"); vkAuthService.signRequest(token, meRequest); String graph = vkAuthService.execute(meRequest).getBody(); diff --git a/src/main/java/com/juick/www/controllers/SocialLogin.java b/src/main/java/com/juick/www/controllers/SocialLogin.java index 1ab0a139..b0738fea 100644 --- a/src/main/java/com/juick/www/controllers/SocialLogin.java +++ b/src/main/java/com/juick/www/controllers/SocialLogin.java @@ -45,6 +45,7 @@ import org.apache.commons.lang3.math.NumberUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.RememberMeServices; @@ -119,7 +120,7 @@ public class SocialLogin { String facebookRedirectUri = redirectBuilder.replacePath("/_fblogin").build().toUriString(); facebookAuthService = facebookBuilder.apiSecret(FACEBOOK_SECRET).callback(facebookRedirectUri) .defaultScope("email").build(FacebookApi.instance()); - vkAuthService = vkBuilder.apiSecret(VK_SECRET).defaultScope("friends,wall,offline").callback(VK_REDIRECT) + vkAuthService = vkBuilder.apiSecret(VK_SECRET).defaultScope("friends,wall,offline,groups").callback(VK_REDIRECT) .build(VkontakteApi.instance()); ServiceBuilder appleSignInBuilder = new ServiceBuilder(appleApplicationId); String appleSignInRedirectUri = redirectBuilder.replacePath("/_apple").build().toUriString(); @@ -194,7 +195,7 @@ public class SocialLogin { @GetMapping("/_twitter") protected void doTwitterLogin(com.juick.model.User user, HttpServletRequest request, - HttpServletResponse response) throws IOException, ExecutionException, InterruptedException { + HttpServletResponse response) throws IOException, ExecutionException, InterruptedException { String hash = StringUtils.EMPTY, request_token = StringUtils.EMPTY, request_token_secret = StringUtils.EMPTY; String verifier = request.getParameter("oauth_verifier"); Cookie[] cookies = request.getCookies(); @@ -279,6 +280,7 @@ public class SocialLogin { long vkID = NumberUtils.toLong(jsonUser.id(), 0); int uid = userService.getUIDbyVKID(vkID); if (uid > 0) { + userService.updateVkUser(vkID, token.getAccessToken(), vkName, vkLink); Cookie c = new Cookie("hash", userService.getHashByUID(uid)); c.setMaxAge(50 * 24 * 60 * 60); response.addCookie(c); @@ -299,9 +301,9 @@ public class SocialLogin { @GetMapping("/_tglogin") public String doDurovLogin(@RequestParam Map<String, String> params, - @RequestParam String hash, - @RequestHeader(value = "referer", required = false) String referer, - HttpServletRequest request, HttpServletResponse response) { + @RequestParam String hash, + @RequestHeader(value = "referer", required = false) String referer, + HttpServletRequest request, HttpServletResponse response) { String dataCheckString = params.entrySet().stream().filter(p -> !p.getKey().equals("hash")) .sorted(Map.Entry.comparingByKey()).map(p -> p.getKey() + "=" + p.getValue()) .collect(Collectors.joining("\n")); @@ -345,7 +347,8 @@ public class SocialLogin { @PostMapping("/_apple") public String doVerifyAppleResponse(HttpServletRequest request, HttpServletResponse response, - @RequestParam Map<String, String> body, HttpSession session) throws InterruptedException, ExecutionException, IOException { + @RequestParam Map<String, String> body, HttpSession session) + throws InterruptedException, ExecutionException, IOException { OAuth2AccessToken token = appleSignInService.getAccessToken(body.get("code")); var jsonNode = jsonMapper.readTree(token.getRawResponse()); var idToken = jsonNode.get("id_token").textValue(); @@ -372,4 +375,35 @@ public class SocialLogin { } throw new HttpBadRequestException(); } + + @Scheduled(fixedRate = 3600000) + public void updatePremium() { + userService.getVkTokens(List.of()) + .forEach(vkUser -> { + var userId = userService.getUIDbyVKID(Long.parseLong(vkUser.getLeft())); + if (userId > 0) { + OAuth2AccessToken token = new OAuth2AccessToken(vkUser.getRight()); + OAuthRequest donRequest = new OAuthRequest(Verb.GET, + "https://api.vk.com/method/donut.isDon?owner_id=-67669480&v=5.131"); + vkAuthService.signRequest(token, donRequest); + try { + Response vkResponse = vkAuthService.execute(donRequest); + if (vkResponse.isSuccessful()) { + logger.info(vkResponse.getBody()); + var response = jsonMapper.readTree(vkResponse.getBody()); + if (response.has("response")) { + var isDon = response.get("response").intValue() > 0; + logger.info("{} is Don: {}", vkUser.getLeft(), isDon); + userService.setPremium(userId, isDon); + } else { + // token is expired or does not have "groups" permissions + userService.updateVkToken(userId, ""); + } + } + } catch (Exception e) { + logger.error("Don request error", e); + } + } + }); + } } diff --git a/src/main/resources/db/migration/V1.46__premium_users.sql b/src/main/resources/db/migration/V1.46__premium_users.sql new file mode 100644 index 00000000..11edb121 --- /dev/null +++ b/src/main/resources/db/migration/V1.46__premium_users.sql @@ -0,0 +1 @@ +alter table users add column premium smallint not null default (0)::smallint; diff --git a/src/main/resources/schema-h2.sql b/src/main/resources/schema-h2.sql index ea979df1..8b786382 100644 --- a/src/main/resources/schema-h2.sql +++ b/src/main/resources/schema-h2.sql @@ -66,6 +66,7 @@ CREATE MEMORY TABLE "PUBLIC"."USERS"( "LASTPM" INTEGER DEFAULT '0' NOT NULL, "LASTPHOTO" INTEGER DEFAULT '0' NOT NULL, "KARMA" SMALLINT DEFAULT '0' NOT NULL, + "PREMIUM" SMALLINT DEFAULT '0' NOT NULL, "LAST_SEEN" TIMESTAMP(6) ); ALTER TABLE "PUBLIC"."USERS" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_4" PRIMARY KEY("ID"); diff --git a/src/main/resources/schema-mysql.sql b/src/main/resources/schema-mysql.sql index e458203f..d0943254 100644 --- a/src/main/resources/schema-mysql.sql +++ b/src/main/resources/schema-mysql.sql @@ -558,6 +558,7 @@ CREATE TABLE `users` ( `lastpm` int(11) NOT NULL DEFAULT 0, `lastphoto` int(11) NOT NULL DEFAULT 0, `karma` smallint(6) NOT NULL DEFAULT 0, + `premium` smallint default '0' not null, `last_seen` timestamp(6) NULL DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `nick` (`nick`) diff --git a/src/main/resources/schema-sqlite.sql b/src/main/resources/schema-sqlite.sql index 84ad015c..ae1f4317 100644 --- a/src/main/resources/schema-sqlite.sql +++ b/src/main/resources/schema-sqlite.sql @@ -227,6 +227,7 @@ CREATE TABLE users ( lastpm bigint DEFAULT (0) NOT NULL, lastphoto bigint DEFAULT (0) NOT NULL, karma smallint DEFAULT (0) NOT NULL, + premium smallint DEFAULT (0) NOT NULL, last_seen timestamp with time zone, UNIQUE(nick) ); diff --git a/src/main/resources/schema-sqlserver.sql b/src/main/resources/schema-sqlserver.sql index 4a683189..34032b67 100644 --- a/src/main/resources/schema-sqlserver.sql +++ b/src/main/resources/schema-sqlserver.sql @@ -8,6 +8,7 @@ CREATE TABLE users ( lastpm bigint DEFAULT (0) NOT NULL, lastphoto bigint DEFAULT (0) NOT NULL, karma smallint DEFAULT (0) NOT NULL, + premium smallint DEFAULT (0) NOT NULL, last_seen datetimeoffset, UNIQUE(nick), PRIMARY KEY (id) diff --git a/src/main/resources/templates/views/partial/message.html b/src/main/resources/templates/views/partial/message.html index 9d54d614..e9ddd3db 100644 --- a/src/main/resources/templates/views/partial/message.html +++ b/src/main/resources/templates/views/partial/message.html @@ -1,7 +1,7 @@ <article class="msg-cont" data-mid="{{ msg.mid }}"> <header class="h"> <span> - <a href="/{{ msg.user.name }}/"><span>{{ msg.user.name }}</span></a> + <a href="/{{ msg.user.name }}/"><span>{{ msg.user.name }}</span>{% if msg.user.premium %}<span style="color: green;"><i data-icon="ei-star" data-size="s"></i></span>{% endif %}</a> </span> <div class="msg-avatar"><a href="/{{ msg.user.name }}/"> <img src="{{ msg.user.avatar }}" alt="{{ msg.user.name }}"/></a> diff --git a/src/main/resources/templates/views/partial/navigation.html b/src/main/resources/templates/views/partial/navigation.html index 159c3d21..105cc568 100644 --- a/src/main/resources/templates/views/partial/navigation.html +++ b/src/main/resources/templates/views/partial/navigation.html @@ -4,6 +4,9 @@ <div id="ctitle"> <a href="/{{ visitor.name }}/"> <img src="{{ visitor.avatar }}" alt=""/>{{ visitor.name }} + {% if visitor.premium %} + <span style="color: green;"><i data-icon="ei-star" data-size="s"></i></span> + {% endif %} {% if not visitor.verified %} <span style="color: red;"><i data-icon="ei-exclamation" data-size="s"></i></span> {% endif %} diff --git a/src/main/resources/templates/views/thread.html b/src/main/resources/templates/views/thread.html index ca74a2ff..84c52282 100644 --- a/src/main/resources/templates/views/thread.html +++ b/src/main/resources/templates/views/thread.html @@ -9,7 +9,7 @@ <a href="/{{ msg.user.name }}/"><img src="{{ msg.user.avatar }}" alt="{{ msg.user.name }}"/></a> </div> <span> - <a href="/{{ msg.user.name }}/"><span>{{ msg.user.name }}</span></a> + <a href="/{{ msg.user.name }}/"><span>{{ msg.user.name }}</span>{% if msg.user.premium %}<span style="color: green;"><i data-icon="ei-star" data-size="s"></i></span>{% endif %}</a> </span> <div class="msg-ts"> {% if msg.FriendsOnly %} @@ -129,7 +129,7 @@ <div class="msg-cont"> <div class="msg-header" data-uri="{{ msg.user.uri }}"> {% if not msg.user.banned %} - <a class="a-username" href="/{{ msg.user.name }}/">{{ msg.user.name }}</a> + <a class="a-username" href="/{{ msg.user.name }}/">{{ msg.user.name }}{% if msg.user.premium %}<span style="color: green;"><i data-icon="ei-star" data-size="s"></i></span>{% endif %}</a> <div class="msg-avatar"> <a class="a-username" href="/{{ msg.user.name }}/"> <img src="{{ msg.user.avatar }}" alt="{{ msg.user.name }}"/> |