Building a new social (or a "chain" of them): your suggestions

Impressive. I'm sure there are some here that understand all that stuff you are talking about, I'm not one obviously; but it doesn't take a genius to spot a genius. Stay on it. Don't seek re-affirmation because I have found in life you'll rarely get it.

If you think it'll work, then block out what the world says and get it up and going because just as you pointed out about predicting the markets, no one can predict if an idea will be successful or not. If you believe in it... that's all that matters. The world is full of nay-sayers, I think the ratio is probably like 99:1. Count me as one of the "1's" however.

Of course I can add nothing technical to your framework lol, but I did notice you left out pets in this list:
Your projects
Your job positions
Your skills
Your research and articles
Stories in the workplace
Your problems at work
Computer science
Algorithms and machine learning
Statistics and quantitative methods
Topics in Mathematics
Topics in Physics
People and companies
Macroeconomic and politics
Work Philosophy and life wisdom
Social media trends
New technologies
New software
New hardware
Real estates deals
Investors lounge, finance
Artworks deals
Equipment deals
Main Languages: C, C++, C#
Main Languages: VB.NET
Main Languages: Java
Main Languages: Assembly
Main Languages, web front end
Main Languages, web back end
Interpreters and data analysis tools
Your hobbies and passions
Health and wealth
Life hacks and useful tips
Chit-chat, news, opinions
Inspiring stories


Pets are a big thing these days. Probably more than ever. I'm sure your cat would agree.
GL and never quit. You've already done more in this thread alone than most ever will. :thumbsup:
~vz
 
Thank you vanzandt. That beautiful encouragement is way too kind of you.


> I did notice you left out pets in this list.


Thank you. Please enumerate all your ideas and suggestions :-) I am also compiling a list for the NY site.

So I will add possible suggestions and then I will submit here again the new list in English too (for the NY site, with items specific to New York, like the slang, Central Park, and so on...). For that, I will need some "serious" help and feedback, as obviously, I do not know well life over there, apart from what we see in the movies and news :-)

The list above was that of the "professional" site (say the LinkedD... "replacement"). "Pets" are currently included in the Rome site (several items dedicated, as Roman cats are famous :-)) and in the ITA-EN cafe exchange site, but I did not include them explicitly for the "professional" site. It might be added actually, although the "passions" item in this list could partially cover it ...


> If you think it'll work, then block out what the world says

I always like to get anything without blocks. Even the negativity because there is always a reason behind any remark, and I always want to understand exactly that reason (if any) to possibly come back stronger :-)


> I think the ratio is probably like 99:1. Count me as one of the "1's" however.

I take note :-)

Impressive. I'm sure there are some here that understand all that stuff you are talking about, I'm not one obviously; but it doesn't take a genius to spot a genius. Stay on it. Don't seek re-affirmation because I have found in life you'll rarely get it.

If you think it'll work, then block out what the world says and get it up and going because just as you pointed out about predicting the markets, no one can predict if an idea will be successful or not. If you believe in it... that's all that matters. The world is full of nay-sayers, I think the ratio is probably like 99:1. Count me as one of the "1's" however.

Of course, I can add nothing technical to your framework lol, but I did notice you left out pets in this list:
...
Pets are a big thing these days. Probably more than ever. I'm sure your cat would agree.
GL and never quit. You've already done more in this thread alone than most ever will. :thumbsup:
~vz
 
To recap a bit, we started from the simple idea of making a new social medium, propaganda free, and now I am messing on 5 different sites :))

Well, the point is that since the engine can be "shared", it's just convenient to have different "incarnations" of a social medium. Why?

Technically, because, for me, being forced to adapt the engine to slightly different "destinations" and languages forces me to a higher level of abstraction, which usually makes the entire code and architecture much more robust, maintainable, and powerful.

Strategically, a network of media is certainly better than just 1 medium. Simply because a user can just by curiosity take a look at the other sites and that creates a multiplier of views and interactions.


The initial magic network "pentacle" is now formed by:

1) A "professional life" site (say a better version of Linkedin :) )

2) A more relaxing and casual site for cultural exchanges between ITA and EN-speaking people or anyway interested in different cultures and languages: Italiano-English Cafè

3) A specialized local medium for Rome, which will contain both classified ads to buy and sell anything, but also discussion forums and topics about all the most characteristic aspects of Rome. This site will use the "Romanesco" dialect and will be also full of funny sayings and proverbs.

4) A site for trading journals and other trading-related stuff. Pretty much similar to ET but on an EU domain, and of course will take care of sending traffic and advertising ET too of course :)

5) A site replicating the idea of the local Rome journal for NYC. This goes well also with site 2) and probably 2-3-5 can generate some good interaction. This will not be just a classified ads site, but will host discussions and every ad will actually potentially become a discussion thread.

For the last one, I am in a bit of trouble both because of the language barrier and because I do not know the city. Anyway, I will give it a preliminary try, and then we can adjust on the fly based on feedback (or even remake it entirely later if necessary :).

For now, I have basically copied the categories I had created for Rome and attempted a brutal "translation", adding some entries.

The first difficulty I found is in sports. In Italy, we do not have much variety, since soccer is sadly dominating, but it seems to me that in the US the situation is much more varied. So I am a bit perplexed about that (probably will need to make a separate entry for any main sport ?).

On the Rome site, I put a lot of traditional proverbs in Romanesco, which are very funny. But I am not able to recreate the same "feeling" for NY, as it seems they do not have a massive tradition of proverbs (do they?)

Some examples of proverbs we have (these are very funny, but very difficult to render in a different culture... even the translation in current Italian loses it all):

https://www.frasimania.it/proverbi-romani/
https://www.lepiubellefrasi.it/proverbi-romani.html
https://frasissime.com/detti-romani/
...


Corrections and suggestions are most welcome:


Manual jobs:
Professionals and trades
Workers
Shops
Catering
Domestic workers
Transportation
Security
Agriculture


Jobs - Assistants, Carers:

Elderly and disabled assistance
House assistance, Alzheimer's, Parkinson's
Animation, children's surveillance
Animal supervision and training

Intellectual work:
Informatics
Engineering
Graphic arts
Journalism
Accounting
Real estate
Healthcare
Aesthetics
Tourism
Show and entertainment
Sales
Customer care
Human resources
Insurance and Banks
Consulting
Legal
Public calls for tenders?

Jobs - Teachers:
School Tutoring
Languages
Music
Singing
Teachers - Other


Jobs - Instructors:

Fitness
Combat disciplines
Bodyweight disciplines
Soft gymnastics
Athletics
Football, Basketball, Baseball, Hockey, Soccer
Rehabilitation, postural gymnastics
Instructors - Other

Getting to know other people:
Company, friendship
More than a friendship
Escort (adult only)
Training Partners
Study Partners
Training groups
Study groups

Things and animals:
Handmade
Collectibles
Antiques
Animals and accessories
Instruments, scores, librettos
Electronics, Cell Phones, Audio
Video, Photography
IT and accessories
Consoles, video games, and accessories
Home & Garden
Work tools, hobbies
Clothing and accessories
Books, magazines, games

Cars, motorcycles, and vehicles:
Cars
Vintage car
Cars - Accessories
Motorcycles
Motorcycles - Off-Road
Vintage motorcycles
Motorcycles - Accessories
Caravans, motorhomes, camping
Boats, nautical
Bikes and accessories
Electric vehicles
Other vehicles

Trade:
Rental and Leasing
Vans, commercial vehicles
Machinery
Large equipment
Commercial furniture
Business, licenses
Investment proposals, equity partners

Gifts:
Gifts: Free items, cleanup
Gifts: Toys, books
Gifts: Animals, puppies

Properties:
Houses, apartments - condo
Houses, villas - independent
Land and cottages
Car shelter, garage
Business premises
Apartments, rooms

Rentals:
Rentals - Box, garage rentals
Rentals - Holiday houses
Rentals - Commercial Premises
Rentals - Other

Being a New Yorker:
Slang
New York cuisine
Songs, Poems, Sayings
History of New York
New York walks
NY videos and photos
Happening in Central Park
Memories of the past
Celebrities Loved by New Yorkers
Movies about NY
YouTubers loved by New Yorkers
NY politicians
DIY of New Yorkers

Being a NY - Typical places:
Famous and typical places of NY
Typical NY shops and craftsmen
Trattorias, typical NY taverns
Typical NY pizzerias
Typical NY bakeries
Typical NY pastry shops
Typical NY bars, cafes, pubs
Typical NYC venues
NY local recommendation

Social:
Centers for the elderly
Shelters and centers for the homeless
Volunteer initiatives
Events, invitations
Parks and attractions
Popular sport
Gyms
Museums, exhibitions, churches
School: from kindergarten to high school
School: university
Public transport
Public services
Bureaucracy and offices

Vox Populi:
Missing/found persons
Missing/found items
It happens on social media, news
Word of mouth, useful info
City of NY Trouble Reporting
Warning of dangers
Reporting scams
Thank others for their help
Neighborhood stories
Criminal and unsolved stories
Beautiful stories



Note that the Rome and New York sites will also host classified ads to buy and sell things, while the other 3 forums are for discussions only.
In particular, the ITA-EN cafe will be the one with the largest array of pure discussion topics.

Note that users of the sites will never be asked for money in any form and all ads will be free. (Any revenues, if any in the far future, may only come from qualified sponsors.)
 
Last edited:
To recap a bit, we started from the simple idea of making a new social medium, propaganda free, and now I am messing on 5 different sites :))

Well, the point is that since the engine can be "shared", it's just convenient to have different "incarnations" of a social medium. Why?

Technically, because, for me, being forced to adapt the engine to slightly different "destinations" and languages forces me to a higher level of abstraction, which usually makes the entire code and architecture much more robust, maintainable, and powerful.

Strategically, a network of media is certainly better than just 1 medium. Simply because a user can just by curiosity take a look at the other sites and that creates a multiplier of views and interactions.


The initial magic network "pentacle" is now formed by:

1) A "professional life" site (say a better version of Linkedin :) )

2) A more relaxing and casual site for cultural exchanges between ITA and EN-speaking people or anyway interested in different cultures and languages: Italiano-English Cafè

3) A specialized local medium for Rome, which will contain both classified ads to buy and sell anything, but also discussion forums and topics about all the most characteristic aspects of Rome. This site will use the "Romanesco" dialect and will be also full of funny sayings and proverbs.

4) A site for trading journals and other trading-related stuff. Pretty much similar to ET but on an EU domain, and of course will take care of sending traffic and advertising ET too of course :)

5) A site replicating the idea of the local Rome journal for NYC. This goes well also with site 2) and probably 2-3-5 can generate some good interaction. This will not be just a classified ads site, but will host discussions and every ad will actually potentially become a discussion thread.

For the last one, I am in a bit of trouble both because of the language barrier and because I do not know the city. Anyway, I will give it a preliminary try, and then we can adjust on the fly based on feedback (or even remake it entirely later if necessary :).

For now, I have basically copied the categories I had created for Rome and attempted a brutal "translation", adding some entries.

The first difficulty I found is in sports. In Italy, we do not have much variety, since soccer is sadly dominating, but it seems to me that in the US the situation is much more varied. So I am a bit perplexed about that (probably will need to make a separate entry for any main sport ?).

On the Rome site, I put a lot of traditional proverbs in Romanesco, which are very funny. But I am not able to recreate the same "feeling" for NY, as it seems they do not have a massive tradition of proverbs (do they?)

Some examples of proverbs we have (these are very funny, but very difficult to render in a different culture...):

https://www.frasimania.it/proverbi-romani/
https://www.lepiubellefrasi.it/proverbi-romani.html
https://frasissime.com/detti-romani/
...


Corrections and suggestions are most welcome:


Manual jobs:
Professionals and trades
Workers
Shops
Catering
Domestic workers
Transportation
Security
Agriculture


Jobs - Assistants, Carers:

Elderly and disabled assistance
House assistance, Alzheimer's, Parkinson's
Animation, children's surveillance
Animal supervision and training

Intellectual work:
Informatics
Engineering
Graphic arts
Journalism
Accounting
Real estate
Healthcare
Aesthetics
Tourism
Show and entertainment
Sales
Customer care
Human resources
Insurance and Banks
Consulting
Legal
Public calls for tenders?

Jobs - Teachers:
School Tutoring
Languages
Music
Singing
Teachers - Other


Jobs - Instructors:

Fitness
Combat disciplines
Bodyweight disciplines
Soft gymnastics
Athletics
Football, Basketball, Baseball, Hockey, Soccer
Rehabilitation, postural gymnastics
Instructors - Other

Getting to know other people:
Company, friendship
More than a friendship
Escort (adult only)
Training Partners
Study Partners
Training groups
Study groups

Things and animals:
Handmade
Collectibles
Antiques
Animals and accessories
Instruments, scores, librettos
Electronics, Cell Phones, Audio
Video, Photography
IT and accessories
Consoles, video games, and accessories
Home & Garden
Work tools, hobbies
Clothing and accessories
Books, magazines, games

Cars, motorcycles, and vehicles:
Cars
Vintage car
Cars - Accessories
Motorcycles
Motorcycles - Off-Road
Vintage motorcycles
Motorcycles - Accessories
Caravans, motorhomes, camping
Boats, nautical
Bikes and accessories
Electric vehicles
Other vehicles

Trade:
Rental and Leasing
Vans, commercial vehicles
Machinery
Large equipment
Commercial furniture
Business, licenses
Investment proposals, equity partners

Gifts:
Gifts: Free items, cleanup
Gifts: Toys, books
Gifts: Animals, puppies

Properties:
Houses, apartments - condo
Houses, villas - independent
Land and cottages
Car shelter, garage
Business premises
Apartments, rooms

Rentals:
Rentals - Box, garage rentals
Rentals - Holiday houses
Rentals - Commercial Premises
Rentals - Other

Being a New Yorker:
Slang
New York cuisine
Songs, Poems, Sayings
History of New York
New York walks
NY videos and photos
Happening in Central Park
Memories of the past
Celebrities Loved by New Yorkers
Movies about NY
YouTubers loved by New Yorkers
NY politicians
DIY of New Yorkers

Being a NY - Typical places:
Famous and typical places of NY
Typical NY shops and craftsmen
Trattorias, typical NY taverns
Typical NY pizzerias
Typical NY bakeries
Typical NY pastry shops
Typical NY bars, cafes, pubs
Typical NYC venues
NY local recommendation

Social:
Centers for the elderly
Shelters and centers for the homeless
Volunteer initiatives
Events, invitations
Parks and attractions
Popular sport
Gyms
Museums, exhibitions, churches
School: from kindergarten to high school
School: university
Public transport
Public services
Bureaucracy and offices

Vox Populi:
Missing/found persons
Missing/found items
It happens on social media, news
Word of mouth, useful info
City of NY Trouble Reporting
Warning of dangers
Reporting scams
Thank others for their help
Neighborhood stories
Criminal and unsolved stories
Beautiful stories



Note that the Rome and New York sites will also host classified ads to buy and sell things, while the other 3 forums are for discussions only.
In particular, the ITA-EN cafe will be the one with the largest array of pure discussion topics.

Note that users of the sites will never be asked for money in any form and all ads will be free. (Any revenues, if any in the far future, may only come from qualified sponsors.)
Might as well add some local flavor to the mix....

"Recipes from around the world"

For example, I'd love to see the various pasta sauce recipes from small villages across Italy. And pizza dough lol.
Or any other specialty from any other region of the world. Like prawns masala from India or something. Local recipes are cool.
 
Might as well add some local flavor to the mix....

"Recipes from around the world"

For example, I'd love to see the various pasta sauce recipes from small villages across Italy. And pizza dough lol.
Or any other specialty from any other region of the world. Like prawns masala from India or something. Local recipes are cool.


For sure. When it comes to eating, Italy is the right place, and from the top down I'd say it is a crescendo of goodness :)

Here are a few recipes I found in English:
https://www.seriouseats.com/essential-italian-pasta-sauces
https://thiswaytoitaly.com/best-popular-italian-sauces/
https://annainthekitchen.com/best-italian-pasta-sauces/
https://www.eataly.com/us_en/magazine/recipes/first-course-recipes/top-5-italian-sauces
...

pizza:
https://www.italiadelight.it/traditional-italian-pizzas-how-many-are-there/?lang=en
https://www.idealista.it/en/news/li...28/2491-most-popular-authentic-italian-pizzas
...
 
Let's see something about the error and messaging system.

I believe it is important to give full insight to a user about what is going on inside the app and about possible errors. Nothing is more frustrating than some incomprehensible message delivered through a modal window. (Well, unless it is required for confirmation purposes.)

A classic of (older conception) msft programs, blocking a program for anything, and spreading very bad programming habits.

Let's start by saying that I believe that modal windows for delivering simple messages should be a just cause for dismissal :) ( just kidding :))

Now, in web app errors or messages can come essentially:

1) from the client
2) from the server

A simple example of 1) is when you type your email in a login form and the application informs you that your email has an invalid format. That kind of messaging happens locally because the check does not involve any operation that needs to be done on the server (such as querying a DB or uploading a file, or whatever).

The simple message can be delivered to the user in a temporary message flashing quickly on the screen because a quick hint is sufficient. No need to insult the intelligence of the user or to do much more (like alert() functions or other nonsense of the sort.).

A simple example of 2) is for instance when you are subscribing to the site and you input an email or a nickname that is already in use. In that case, there is no way for the local browser and javascript to know that, and the message is coming from the server after it has determined that the email or nick is already inside the database.

Clearly, the possible errors and messages are a very large number, at least as many as the possible interaction of the user with the server (so any kind of DB interaction or file transmission, etc.).

The messages (error or some operation confirmation) that originates from the server are transmitted to the client and the receiving javascript will take care of presenting that information to the user in a proper noninvasive way.

So in practice, we can imagine the following scheme:

1a- Errors coming from the server
1b- Messages coming from the server

2a- Errors coming from the client
2b- Messages coming from the client

Then there are 2 possible ways of presenting the material:

T) A "temporary" way: quick information is briefly "flashed" to the user, and can be automatically dismissed because there is no need to bother the user too much

P) A "permanent" way: in this case, a nonmodal window will present the information so that the user can read it at his pace (copy if necessary, etc.) and close it with a click.

An example of T), is positive feedback on a file upload. We can just quickly flash the information. (Even if the user does not see it, it does not matter: it's just "entertainment" :) )

An example of P), could be the user attempting to upload an executable, and in that case, we may provide him a more detailed explanation in a window that he can readily close with just one click.

Another point is about stacking errors and messages. For instance, if you are uploading 20 or more attachments, some of them could give errors and some could land fine. So we want to stack all errors with their causes together in a unique information window, without blocking the upload operation, but just reporting on what could not be done within the required loop.

So you see that, in order to keep into account all these necessities, we need at least some planning for a good (nonmodal) messaging system :)

And certainly not the alert() method :)
 
Last edited:
I am currently working on the post editor/viewer, to make it more intuitive.

This takes a considerable amount of patience, as this is the "core" of the client-side part of the application, and where the possible users will spend most of their time.

I am replicating the edit/save button in 2 different locations so that they will be always easily reachable. This clearly forces us to create separate objects for all this stuff that is replicated.

The buttons could be of the type: edit, save, save and close, and close. discard changes, remove post, and so on.

Also depending on the "state" of the editor/viewer (document saved or not, editing or just viewing, etc) the configuration of the shown button has to change, so one has to put in place all these mechanisms to manage dynamically the visibility of these buttons.

In order to do that I have practically dissected the whole editor/viewer and rewritten most functionalities in the form of distinct classes (objects) so I can easily move them around to find the best locations.

When I work on the layout I like to set all the divs' backgrounds to some very flashy colors, so that I can see precisely where each element ends and how are relatively positioned.

In the picture below you can see this "harlequinade", and actually also a view that no user will ever see :), where I have in view both the viewer and the editor for the same post simultaneously visible. In the final application, the user will only see one at a time of these 2 components (as he will either be viewing or editing). (In reality, the application keeps both and moves the HTML between these windows, according to necessity).

upload_2023-7-16_16-17-46.png


Clearly, when done, the harlequinade will disappear and we will be back to smooth and cozy colors :)
 
Last edited:
I finished reassembling the post editor/viewer.

Here is a short demo of the current state (it's the ita-en cafe site):


I am now refining and restructuring code, to make it more "maintainable" and compact, by making reusable objects wherever useful.

The post editor/viewer is the largest control in the application, totaling several thousands of lines of code, most of which define other objects.

For source code lovers, I am attaching the code controlling the editor buttons, which were the cause of the last changes we made.

In practice, the scheme is as follows. The viewer/editor is an interface "control" that can either show the user the post or let him edit, depending on if he is the author and is in edit mode or not.

It is essentially made of two graphics areas (viewer/editor), only one of which is displayed at one time. When the author starts editing, a post is created on the server. On view (posts are paginated), the post is transferred from the server to the viewer, and in the edit, the post is transferred from the "viewer" to the "editor". If saved, the post is sent back to the server with changes. If changes are discarded, the editor is just closed and we are back to the "viewer". If a user is not the author of a post, the "editor" part of the control is not created at all, and there will only be the "viewer" component.


upload_2023-7-19_12-35-24.png


"Editor" and "viewer" behave differently. Apart from the fact that the editor has obviously all the editing functionalities, also the way the text is displayed is different. For the viewer window, in fact, we do not desire any scrolling in the Y direction. While it is useful to have while editing, the editor window will automatically fit the text while the editor maintains a scrolling window.

While in the "editor", we can resize images and videos, while in the viewer, we can only click on images to show them at their original size if they are larger than shown (similar to what happens here on ET, but inside the window, instead of "popping up").

upload_2023-7-19_12-35-3.png


Here is some code to show the interplay between buttons:

Code:
class SetOfEditorButtons {

    Create_cSetOfEditorButtons(pev, LarghezzaBottone) {

        this.pev = pev;

        this.div_SetOfEditorButtons_Container = document.createElement('div');
        this.div_SetOfEditorButtons_Container.style.cssText = `display:inline-block; vertical-align:top; padding:10px`;

        //bottone Save
        this.button_SavePostOnline = document.createElement('button');
        setup_BUTTON_LOOK_ANIMATION(this.button_SavePostOnline, `${_SiteJS.ADict.SAVE_ONLINE_BUTTON_TEXT}`);
        this.button_SavePostOnline.style.cssText += `display:block; width:${LarghezzaBottone}; color:yellow; background-color:red; margin-top:10px;`;
        this.div_SetOfEditorButtons_Container.appendChild(this.button_SavePostOnline);

        //bottone Save and Exit
        this.button_SaveAndExit = document.createElement('button');
        setup_BUTTON_LOOK_ANIMATION(this.button_SaveAndExit, `${_SiteJS.ADict.SAVE_AND_EXIT_BUTTON_TEXT}`);
        this.button_SaveAndExit.style.cssText += `display:block; width:${LarghezzaBottone}; color:yellow; background-color:red; margin-top:10px;`;
        this.div_SetOfEditorButtons_Container.appendChild(this.button_SaveAndExit);

        //bottone discard unsaved changes
        this.button_DiscardPostChanges = document.createElement('button');
        setup_BUTTON_LOOK_ANIMATION(this.button_DiscardPostChanges, _SiteJS.ADict.DISCARD_CHANGES_BUTTON_TEXT);
        this.button_DiscardPostChanges.style.cssText += `display:block; width:${LarghezzaBottone}; margin-top:10px;`;
        this.div_SetOfEditorButtons_Container.appendChild(this.button_DiscardPostChanges);

        //bottone exit post edit / view online
        this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server = document.createElement('button');
        setup_BUTTON_LOOK_ANIMATION(this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server, `${_SiteJS.ADict.RETURN_ONLINE_BUTTON_TEXT}`);
        this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.style.cssText += `display:block; width:${LarghezzaBottone}; color: cyan; margin-top:10px;`;
        this.div_SetOfEditorButtons_Container.appendChild(this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server);


        //remove post button and remove functionality
        this.button_RemovePost = CreateRemoveButton(LarghezzaBottone, this.pev.pep);            //come funzione perche serve anche per il viewer

        if (this.button_RemovePost) {
            this.button_RemovePost.style.marginTop = "40px";
            this.div_SetOfEditorButtons_Container.appendChild(this.button_RemovePost)
        }

        //salvataggio post e immagini
        this.button_SavePostOnline.onclick = async () => {
            await this.pev.da_EDITOR_Salva_Post_Su_Server();
        };

        //save and exit
        this.button_SaveAndExit.onclick = async () => {
            await this.pev.da_EDITOR_Salva_Post_Su_Server();
            await this.pev.da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server();
        };

        //ritorno online senza salvare
        this.button_DiscardPostChanges.onclick = () => {

            if (!this.pev.postIsUnchangedOrJustSaved) {    //se gia salvato non serve
                if (confirm(_SiteJS.ADict.EDITOR_AVVISO_LOSE_CHANGES)) {

                    this.pev.div_EditorWindow.innerHTML = "";
                    this.postIsUnchangedOrJustSaved = true;

                    //switch a viewer
                    this.pev.Author_Is_In_EDITOR = false;
                    this.pev.StylesAndInterfaceDependingOnEditStatus();
                }
            }
        };

        this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.onclick = async () => {
            await this.pev.da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server();
        };

        this.setButtons_DEPENDING_ON_EDIT_STATE();

    }

    setButtons_DEPENDING_ON_EDIT_STATE() {

        if (!this.pev.isEditable) {
            notifyUnexpected();
        }

        if (this.button_RemovePost) {
            if (RemoveButtonFunctionalityHasExpired(this.pev.pep)) { this.button_RemovePost.remove() }
        }

        if (this.pev.Author_Is_In_EDITOR) {

            if (this.pev.postIsUnchangedOrJustSaved) {
                this.button_SavePostOnline.style.display = "none";                                  //save online
                this.button_DiscardPostChanges.style.display = "none";                              //discard changes
                this.button_SaveAndExit.style.display = "none";
                this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.style.display = "block";          //exit edit

            } else {
                this.button_SavePostOnline.style.display = "block";
                this.button_DiscardPostChanges.style.display = "block";
                this.button_SaveAndExit.style.display = "block";
                this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.style.display = "none";
            }

        } else {

            this.button_SavePostOnline.style.display = "none";
            this.button_DiscardPostChanges.style.display = "none";
            this.button_SaveAndExit.style.display = "none";
            this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.style.display = "none";
        }
    }
}

class SetOfViewerButtons {

    Create_cSetOfViewerButtons(pev, LarghezzaBottone, InVerticale) {

        this.pev = pev;

        this.div_cSetOfViewerButtons_Container = document.createElement('div');
        this.div_cSetOfViewerButtons_Container.style.cssText = `display:inline-flex; padding:10px; `;

        if (InVerticale) {
            this.div_cSetOfViewerButtons_Container.style.flexDirection = "column";
        } else {
            this.div_cSetOfViewerButtons_Container.style.flexDirection = "row";
            this.div_cSetOfViewerButtons_Container.style.marginLeft = "40px";
        }

        //bottone Edit
        this.button_EditPost = document.createElement('button');
        setup_BUTTON_LOOK_ANIMATION(this.button_EditPost, `Edit ✍️`);
        this.button_EditPost.style.cssText += `width:${LarghezzaBottone};`;
        this.div_cSetOfViewerButtons_Container.appendChild(this.button_EditPost);


        //remove post button and remove functionality
        this.button_RemovePost = CreateRemoveButton(LarghezzaBottone, this.pev.pep);      //come funzione perche serve anche per editor

        if (this.button_RemovePost) {

            if (InVerticale) {
                this.button_RemovePost.style.marginTop = "40px";
            } else {
                this.button_RemovePost.style.marginLeft = "40px";
                this.button_RemovePost.style.width = "auto";
            }

            this.div_cSetOfViewerButtons_Container.appendChild(this.button_RemovePost)
        }


        //aggancio handler per cambiare stato edit/view con bottone
        this.button_EditPost.onclick = () => {

            if (this.pev.Author_Is_In_EDITOR) {
                tempNotify("Already in Edit mode", false);
                return;
            }
            this.pev.vaiDaVIEW_Mode_A_EDIT_Mode();   //copia contenuto viewer in editor
        };

        this.setButtons_DEPENDING_ON_EDIT_STATE();

    }

    setButtons_DEPENDING_ON_EDIT_STATE() {

        if (!this.pev.isEditable) {
            notifyUnexpected();
        }

        if (this.button_RemovePost) {
            if (RemoveButtonFunctionalityHasExpired(this.pev.pep)) { this.button_RemovePost.remove() }
        }

        if (this.pev.Author_Is_In_EDITOR) {
            this.button_EditPost.display = "none";
        } else {
            this.button_EditPost.display = "block";
        }
    }
}


function CreateRemoveButton(LarghezzaBottone, pep) {

    if (RemoveButtonFunctionalityHasExpired(pep)) { return }

    //bottone per rimuovere post
    let button_RemovePost = document.createElement('button');
    setup_BUTTON_LOOK_ANIMATION(button_RemovePost, _SiteJS.ADict.REMOVE_POST_BUTTON_TEXT);
    button_RemovePost.style.cssText += `color:yellow; padding:10px; width:${LarghezzaBottone}`;

    button_RemovePost.onclick = async () => {

        let elapsedHours = (new Date() - pep.ThreadPost_Current.DateOfPostCreation) / 3600000;

        if (elapsedHours > 1) {
            tempNotify("Post can't be removed after more than 1 hour");
            button_RemovePost.remove();
            return;
        }

        if (!confirm("Confirm post removal?")) { return }

        let myFormData = new FormData();
        myFormData.append("xhrPostPurpose", "removePost");
        myFormData.append("PostID", pep.ThreadPost_Current.PostID);
        myFormData.append("ThreadID", pep.ThreadPost_Current.ThreadID);

        let xhr = await PostFormData(myFormData, pep.aspxPageTarget, `Removing post id: ${pep.ThreadPost_Current.PostID} thread id: ${pep.ThreadPost_Current.ThreadID}`);

        if (xhr) {
            await pep.afterPostRemove_callBack(xhr);
        } else {
            tempNotify(`Failed to remove post`)
        }
    };

    return button_RemovePost;

}


upload_2023-7-19_12-41-48.png
 
Over the weekend, I have been working to add another feature, that is showing who is following who.

Later I might even create a "network chart" if it is worth it, but for the moment I am just listing in a brutal way, in the user profile, who are the followers and who is followed by the user.

upload_2023-7-24_13-15-37.png



In the meantime, I am thinking about the general looks of the media and watching some videos about NYC to make sure I do not miss the obvious. For Rome, I am switching to yellow and red, as we have a tradition of those colors.
See, for instance, the soccer team logo:

https://it.wikipedia.org/wiki/Associazione_Sportiva_Roma

140px-AS_Roma_Logo_2017.svg.png


One video on NYC that I found pretty useful and informative is this one because it enumerates the main facts in a pretty schematic way:


Thank you
to the creator! :)

If you recall, we have added a table for the followers:

upload_2023-7-24_13-26-49.png


The Js client code is similar in concept to the search we have seen before. On the server side, a query like the following will take care of retrieving, for instance, the users who are followed by a given user:

Code:
public List<UserInfo> Users_Seguiti_Da_Utente(int UserID)
{
    string MySQL = "SELECT FollowedUsers.FollowedUserID, FollowedUsers.DateSubscriptionCreated, Users.* FROM FollowedUsers LEFT JOIN Users ON FollowedUsers.FollowedUserID=Users.UserID WHERE " + " FollowedUsers.UserID=@UserID AND Users.StatusUser=0 ORDER BY FollowedUsers.DateSubscriptionCreated DESC;";

    using (var MyConn = this.MakeConnection())
    {
        MyConn.Open();

        using (var MyCmd = this.MakeCommand(MySQL, MyConn))
        {
            MyCmd.Parameters.Add("@UserID", System.Data.OleDb.OleDbType.Integer).Value = UserID;

            using (var r = MyCmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection))
            {
                if (r.HasRows)
                {
                    List<UserInfo> ListaUsers = new List<UserInfo>();

                    while (r.Read())
                    {
                        // skippo i primi 2 campi
                        int startIndex = 2;
                        UserInfo UserInfo = this.Fill_UserInfo_FromDBFields(r, startIndex);
                        ListaUsers.Add(UserInfo);
                    }
                    return ListaUsers;
                }
            }
        }
    }

    return null;
}
 
Last edited:
Working on refinements and "cleaning" and especially thinking about the suitable categories to add (especially for NYC).

I have added another table to the DB (for future weekly digest) and removed/added some fields from the login table (instead of recording postId or threadId for direct access on "fast login", I am just recording the entire query string, which seems more general. I have also removed the "notification flags" from the "extended user info" and dedicated specific tables to notifications management).

current situation :-)

upload_2023-7-26_10-30-46.png
 
Back
Top