diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py
index 4a25c9d6fa8aa36e12a89dec3e4b195e3199937f..3b35b9122a08dbe1eae68dbc5eed0dfd088cb5f0 100644
--- a/blenderkit/__init__.py
+++ b/blenderkit/__init__.py
@@ -1730,12 +1730,18 @@ class BlenderKitAddonPreferences(AddonPreferences):
 
     thumb_size: IntProperty(name="Assetbar thumbnail Size", default=96, min=-1, max=256)
 
+    #counts usages so it can encourage user after some time to do things.
     asset_counter: IntProperty(name="Usage Counter",
                                description="Counts usages so it asks for registration only after reaching a limit",
                                default=0,
                                min=0,
                                max=20000)
 
+    notifications_counter: IntProperty(
+        name='Notifications Counter',
+        description='count users notifications',
+        default=0,
+    )
     # this is now made obsolete by the new popup upon registration -ensures the user knows about the first search.
     # first_run: BoolProperty(
     #     name="First run",
diff --git a/blenderkit/asset_bar_op.py b/blenderkit/asset_bar_op.py
index d13c376737df03d9242278136a3158156d72436a..3403625c669841a8905bf1ac4b7604ef110c5e16 100644
--- a/blenderkit/asset_bar_op.py
+++ b/blenderkit/asset_bar_op.py
@@ -788,7 +788,7 @@ class BlenderKitAssetBarOperator(BL_UI_OT_draw_operator):
     def search_more(self):
         sro = bpy.context.window_manager.get('search results orig')
         if sro is None:
-            return;
+            return
         if sro.get('next') is None:
             return
         search_props = utils.get_search_props()
diff --git a/blenderkit/comments_utils.py b/blenderkit/comments_utils.py
index cf6ccd0675c063bacd0b14e4b2d802b88d253ecd..23a1740571b4fca71bdd58f81e6aee13ed3e5367 100644
--- a/blenderkit/comments_utils.py
+++ b/blenderkit/comments_utils.py
@@ -51,13 +51,13 @@ def upload_comment_thread(url, comment='', api_key=None):
     # try:
     r = rerequests.put(url, data=data, verify=True, headers=headers)
     print(r)
-    print(dir(r))
+    # print(dir(r))
     print(r.text)
     # except requests.exceptions.RequestException as e:
     #     print('ratings upload failed: %s' % str(e))
 
 
-def upload_comment_flag_thread(url, comment_id='', flag='like', api_key=None):
+def upload_comment_flag_thread( asset_id = '', comment_id='', flag='like', api_key=None):
     ''' Upload rating thread function / disconnected from blender data.'''
     headers = utils.get_headers(api_key)
 
@@ -68,15 +68,21 @@ def upload_comment_flag_thread(url, comment_id='', flag='like', api_key=None):
         "comment": comment_id,
         "flag": flag,
     }
+    url = paths.get_api_url() + 'comments/feedback/'
 
     # try:
     r = rerequests.post(url, data=data, verify=True, headers=headers)
-    print(r)
-    print(dir(r))
     print(r.text)
-    # except requests.exceptions.RequestException as e:
-    #     print('ratings upload failed: %s' % str(e))
 
+    #here it's important we read back, so likes are updated accordingly:
+    get_comments(asset_id, api_key)
+
+
+def send_comment_flag_to_thread(asset_id = '', comment_id='', flag='like', api_key = None):
+    '''Sens rating into thread rating, main purpose is for tasks_queue.
+    One function per property to avoid lost data due to stashing.'''
+    thread = threading.Thread(target=upload_comment_flag_thread, args=(asset_id, comment_id, flag, api_key))
+    thread.start()
 
 def send_comment_to_thread(url, comment, api_key):
     '''Sens rating into thread rating, main purpose is for tasks_queue.
@@ -100,6 +106,14 @@ def get_comments_local(asset_id):
         return comments
     return None
 
+def get_comments_thread(asset_id, api_key):
+    thread = threading.Thread(target=get_comments, args=([asset_id, api_key]), daemon=True)
+    thread.start()
+
+
+def get_comments_thread(asset_id, api_key):
+    thread = threading.Thread(target=get_comments, args=([asset_id, api_key]), daemon=True)
+    thread.start()
 
 def get_comments(asset_id, api_key):
     '''
@@ -120,11 +134,12 @@ def get_comments(asset_id, api_key):
     r = rerequests.get(url, params=params, verify=True, headers=headers)
     if r is None:
         return
+    print(r.status_code)
     if r.status_code == 200:
         rj = r.json()
-        comments = []
         # store comments - send them to task queue
-
+        # print('retrieved comments')
+        # print(rj)
         tasks_queue.add_task((store_comments_local, (asset_id, rj['results'])))
 
         # if len(rj['results'])==0:
@@ -132,20 +147,21 @@ def get_comments(asset_id, api_key):
         #     tasks_queue.add_task((store_rating_local_empty,(asset_id,)))
         # return ratings
 
+
+def store_notifications_count_local(all_count):
+    '''Store total count of notifications on server in preferences'''
+    user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
+    user_preferences.notifications_counter = all_count
+
 def store_notifications_local(notifications):
+    '''Store notifications in Blender'''
     bpy.context.window_manager['bkit notifications'] = notifications
 
-def count_unread_notifications():
-    notifications = bpy.context.window_manager.get('bkit notifications')
-    if notifications is None:
-        return 0
-    unread = 0
-    for n in notifications:
-        
-        if n['unread'] == 1:
-            unread +=1
-    print('counted', unread)
-    return unread
+def count_all_notifications():
+    '''Return count of all notifications on server'''
+    user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
+    return user_preferences.notifications_counter
+
 
 def check_notifications_read():
     '''checks if all notifications were already read, and removes them if so'''
@@ -158,14 +174,14 @@ def check_notifications_read():
     bpy.context.window_manager['bkit notifications'] = None
     return True
 
-def get_notifications(api_key, unread_count = 1000):
+def get_notifications(api_key, all_count = 1000):
     '''
     Retrieve notifications from BlenderKit server. Can be run from a thread.
 
     Parameters
     ----------
     api_key
-    unread_count
+    all_count
 
     Returns
     -------
@@ -174,14 +190,16 @@ def get_notifications(api_key, unread_count = 1000):
 
     params = {}
 
-    url = paths.get_api_url() + 'notifications/api/unread_count/'
+    url = paths.get_api_url() + 'notifications/all_count/'
     r = rerequests.get(url, params=params, verify=True, headers=headers)
     if r.status_code ==200:
         rj = r.json()
+        print(rj)
         # no new notifications?
-        if unread_count >= rj['unreadCount']:
+        if all_count >= rj['allCount']:
+            tasks_queue.add_task((store_notifications_count_local, ([rj['allCount']])))
+
             return
-    print('notifications', unread_count, rj['unreadCount'])
     url = paths.get_api_url() + 'notifications/unread/'
     r = rerequests.get(url, params=params, verify=True, headers=headers)
     if r is None:
diff --git a/blenderkit/download.py b/blenderkit/download.py
index 9fb48073842863cfa1dfab6a6a75b0445073ac6f..f33e636fea69c26583dd8f3961c4a2c8649c18b1 100644
--- a/blenderkit/download.py
+++ b/blenderkit/download.py
@@ -1421,7 +1421,7 @@ class BlenderkitDownloadOperator(bpy.types.Operator):
         # if self.close_window:
         #     context.window.cursor_warp(event.mouse_x-1000, event.mouse_y - 1000);
 
-        print(self.asset_base_id)
+        # print(self.asset_base_id)
         wm = context.window_manager
         # only make a pop up in case of switching resolutions
         if self.invoke_resolution:
diff --git a/blenderkit/search.py b/blenderkit/search.py
index 0464f5114b4b59275f6506e05b2b97d0f9ff366d..fc716fdc10b507adcb1493d39eb1ed386c207534 100644
--- a/blenderkit/search.py
+++ b/blenderkit/search.py
@@ -108,8 +108,8 @@ def refresh_notifications_timer():
     ''' this timer gets notifications.'''
     preferences = bpy.context.preferences.addons['blenderkit'].preferences
     fetch_server_data()
-    unread_notifications_count = comments_utils.count_unread_notifications()
-    comments_utils.get_notifications(preferences.api_key, unread_count = unread_notifications_count)
+    all_notifications_count = comments_utils.count_all_notifications()
+    comments_utils.get_notifications(preferences.api_key, all_count = all_notifications_count)
     return 300
 
 
@@ -730,7 +730,8 @@ def write_gravatar(a_id, gravatar_path):
         adata['gravatarImg'] = gravatar_path
 
 
-def fetch_gravatar(adata):
+def fetch_gravatar(adata = None):
+
     '''
     Gets avatars from blenderkit server
     Parameters
@@ -739,7 +740,7 @@ def fetch_gravatar(adata):
 
     '''
     # utils.p('fetch gravatar')
-
+    print(adata)
     # fetch new avatars if available already
     if adata.get('avatar128') is not None:
         avatar_path = paths.get_temp_dir(subdir='bkit_g/') + adata['id'] + '.jpg'
@@ -784,7 +785,9 @@ fetching_gravatars = {}
 
 
 def get_author(r):
-    ''' Writes author info (now from search results) and fetches gravatar if needed.'''
+    ''' Writes author info (now from search results) and fetches gravatar if needed.
+    this is now tweaked to be able to get authors from
+    '''
     global fetching_gravatars
 
     a_id = str(r['author']['id'])
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index add646532d7d5288ae030a598cd7a6afbd3da685..d94d483d642d4d56d1d692a2f6a1df8d720577ae 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -593,7 +593,7 @@ class VIEW3D_PT_blenderkit_profile(Panel):
 
 
 class MarkNotificationRead(bpy.types.Operator):
-    """Visit subcategory"""
+    """Mark notification as read here and also on BlenderKit server"""
     bl_idname = "wm.blenderkit_mark_notification_read"
     bl_label = "Mark notification as read"
     bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
@@ -620,17 +620,70 @@ class MarkNotificationRead(bpy.types.Operator):
         return {'FINISHED'}
 
 
+class LikeComment(bpy.types.Operator):
+    """Mark notification as read here and also on BlenderKit server"""
+    bl_idname = "wm.blenderkit_like_comment"
+    bl_label = "BlenderKit like/dislike comment"
+    bl_options = {'REGISTER', 'UNDO', 'INTERNAL'}
+
+    asset_id: StringProperty(
+        name="Asset Base Id",
+        description="Unique id of the asset (hidden)",
+        default="",
+        options={'SKIP_SAVE'})
+
+    comment_id: bpy.props.IntProperty(
+        name="Id",
+        description="comment id",
+        default=-1)
+
+    flag: bpy.props.StringProperty(
+        name="flag",
+        description="Like/dislike comment",
+        default="like")
+
+    @classmethod
+    def poll(cls, context):
+        return True
+
+    def execute(self, context):
+
+        user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
+        api_key = user_preferences.api_key
+        comments_utils.send_comment_flag_to_thread(asset_id = self.asset_id, comment_id=self.comment_id, flag=self.flag, api_key = api_key)
+        return {'FINISHED'}
+
+
 def draw_notification(self, notification, width = 600):
     layout = self.layout
     box = layout.box()
-
-    firstline = f"user {notification['actor']['id']} {notification['verb']}"
+    print(notification.to_dict())
+    firstline = f"{notification['actor']['string']} {notification['verb']} {notification['target']['string']}"
     box1 = box.box()
     row = box1.row()
     utils.label_multiline(row, text=firstline, width = width)
-    op = row.operator("wm.blenderkit_mark_notification_read", text="", icon='CHECKMARK')
+
+
+
+    op = row.operator("wm.blenderkit_mark_notification_read", text="", icon='CANCEL')
     op.notification_id = notification['id']
-    utils.label_multiline(box, text=notification['description'], width = width)
+    if notification['description']:
+        rows = utils.label_multiline(box, text=notification['description'], width = width)
+        split = rows[-1].split(factor = 0.8)
+
+    else:
+        row = layout.row()
+        split = row.split(factor = 0.8)
+        split.label(text = '')
+        split = split.split()
+    if notification['target']:
+        # row = layout.row()
+        # split = row.split(factor=.8)
+        # split.label(text='')
+        # split = split.split()
+        op = split.operator('wm.blenderkit_url', text='Open page', icon='GREASEPENCIL')
+        op.tooltip = 'Open the browser on the asset page to comment'
+        op.url = paths.get_bkit_url() + notification['target']['url']
 
 def draw_notifications(self, context, width = 600):
     layout = self.layout
@@ -1435,13 +1488,13 @@ def draw_asset_context_menu(layout, context, asset_data, from_panel=False):
 
             row = layout.row()
             row.operator_context = 'INVOKE_DEFAULT'
-            op = layout.operator('wm.blenderkit_fast_metadata', text='Edit Metadata')
+            op = layout.operator('wm.blenderkit_fast_metadata', text='Edit Metadata',icon='GREASEPENCIL')
             op.asset_id = asset_data['id']
             op.asset_type = asset_data['assetType']
 
             if author_id == str(profile['user']['id']):
                 row.operator_context = 'EXEC_DEFAULT'
-                op = layout.operator('wm.blenderkit_url', text='Edit Metadata (browser)')
+                op = layout.operator('wm.blenderkit_url', text='Edit Metadata (browser)', icon='GREASEPENCIL')
                 op.url = paths.get_bkit_url() + paths.BLENDERKIT_USER_ASSETS + f"/{asset_data['assetBaseId']}/?edit#"
 
             row.operator_context = 'INVOKE_DEFAULT'
@@ -2036,7 +2089,13 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties):
             op = name_row.operator('view3d.close_popup_button', text='', icon='CANCEL')
 
     def draw_comment(self, context, layout, comment, width=330):
-        box = layout.box()
+        row = layout.row()
+        # print(comment)
+        if comment['level']>0:
+            split = row.split(factor = 0.05 * comment['level'])
+            split.label(text='')
+            row = split.split()
+        box = row.box()
         box.emboss = 'NORMAL'
         row = box.row()
         split = row.split(factor = 0.8)
@@ -2045,7 +2104,9 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties):
             role_text = f" - moderator"
         else:
             role_text = ""
-        split.label(text=f"{comment['submitDate']} - {comment['userName']}{role_text}")
+        row = split.row()
+        row.enabled = False
+        row.label(text=f"{comment['submitDate']} - {comment['userName']}{role_text}")
         removal = False
         likes = 0
         dislikes = 0
@@ -2058,13 +2119,33 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties):
                 removal = True
         # row = box.row()
         split1 = split.split()
-        split1.label(text=str(likes), icon='TRIA_UP')
-        split1.label(text=str(dislikes), icon='TRIA_DOWN')
+        # split1.emboss = 'NONE'
+        op = split1.operator('wm.blenderkit_like_comment', text=str(likes), icon='TRIA_UP')
+        op.asset_id = self.asset_data['assetBaseId']
+        op.comment_id = comment['id']
+        op.flag = 'like'
+        op = split1.operator('wm.blenderkit_like_comment', text=str(dislikes), icon='TRIA_DOWN')
+        op.asset_id = self.asset_data['assetBaseId']
+        op.comment_id = comment['id']
+        op.flag = 'dislike'
+        # op = split1.operator('wm.blenderkit_like_comment', text='report', icon='ERROR')
+        # op.asset_id = self.asset_data['assetBaseId']
+        # op.comment_id = comment['id']
+        # op.flag = 'removal'
         if removal:
+            row.alert = True
             row.label(text='', icon='ERROR')
 
-        utils.label_multiline(box, text=comment['comment'], width=width)
+        rows = utils.label_multiline(box, text=comment['comment'], width=width * (1 - 0.05 * comment['level']))
+
 
+        row = rows[-1]
+        split = row.split(factor=.8)
+        split.label(text='')
+        split = split.split()
+        op = split.operator('wm.blenderkit_url', text='Reply', icon='GREASEPENCIL')
+        op.tooltip = 'Open the browser on the asset page to comment'
+        op.url = paths.get_bkit_url() + f"/asset-gallery-detail/{self.asset_data['id']}/"
         # box.label(text=str(comment['flags']))
 
     def draw(self, context):
@@ -2094,9 +2175,11 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties):
         tip_box.label(text=self.tip)
         # comments
         if utils.profile_is_validator() and bpy.app.debug_value == 2:
+            comments = bpy.context.window_manager.get('asset comments', {})
+            self.comments = comments.get(self.asset_data['assetBaseId'], [])
             if self.comments is not None:
                 for comment in self.comments:
-                    self.draw_comment(context, layout, comment)
+                    self.draw_comment(context, layout, comment, width = self.width)
 
     def execute(self, context):
         wm = context.window_manager
@@ -2132,8 +2215,8 @@ class AssetPopupCard(bpy.types.Operator, ratings_utils.RatingsProperties):
             user_preferences = bpy.context.preferences.addons['blenderkit'].preferences
             api_key = user_preferences.api_key
             comments = comments_utils.get_comments_local(asset_data['assetBaseId'])
-            if comments is None:
-                comments_utils.get_comments(asset_data['assetBaseId'], api_key)
+            # if comments is None:
+            comments_utils.get_comments_thread(asset_data['assetBaseId'], api_key)
             comments = bpy.context.window_manager.get('asset comments', {})
             self.comments = comments.get(asset_data['assetBaseId'], [])
 
@@ -2478,6 +2561,7 @@ classes = (
     ClosePopupButton,
     BlenderKitWelcomeOperator,
     MarkNotificationRead,
+    LikeComment,
     ShowNotifications,
 )
 
diff --git a/blenderkit/utils.py b/blenderkit/utils.py
index d09c369bac72d31663f3332642601391e591142e..5bbe96af745779b941a2a8cbe8648292bb0042a4 100644
--- a/blenderkit/utils.py
+++ b/blenderkit/utils.py
@@ -927,10 +927,11 @@ def label_multiline(layout, text='', icon='NONE', width=-1, max_lines=10):
 
     Returns
     -------
-    True if max_lines was overstepped
+    rows of the text(to add extra elements)
     '''
+    rows = []
     if text.strip() == '':
-        return
+        return [layout.row()]
     text = text.replace('\r\n', '\n')
     lines = text.split('\n')
     if width > 0:
@@ -946,7 +947,9 @@ def label_multiline(layout, text='', icon='NONE', width=-1, max_lines=10):
             if i < 1:
                 i = threshold
             l1 = l[:i]
-            layout.label(text=l1, icon=icon)
+            row = layout.row()
+            row.label(text=l1, icon=icon)
+            rows.append(row)
             icon = 'NONE'
             l = l[i:].lstrip()
             li += 1
@@ -954,10 +957,12 @@ def label_multiline(layout, text='', icon='NONE', width=-1, max_lines=10):
                 break;
         if li > max_lines:
             break;
-        layout.label(text=l, icon=icon)
+        row = layout.row()
+        row.label(text=l, icon=icon)
+        rows.append(row)
         icon = 'NONE'
-    if li > max_lines:
-        return True
+    # if li > max_lines:
+    return rows
 
 
 def trace():